Кнопки на Api
Кнопка есть, куда сувать картинку не знаю.
Народ, помогите зелёному! Как писать кнопки с Bitmap-ом (можно из ресурса) и обрабатывать их нажатия? VCL использовать не хочется, т.к прога маленькая-переключение режимов экрана при запуске компа.
Кнопка есть, куда сувать картинку не знаю.
#define BCM_SETIMAGELIST (BCM_FIRST + 0x0002)
...
HICON hIcon, hIcon0;
BUTTON_IMAGELIST biSort = { 0 };
biSort.himl = ImageList_Create(20, 20, ILC_COLOR16 | ILC_MASK, 5, 0);
biSort.uAlign = 5;
hIcon = AfxGetApp()->LoadIcon(IDI_SORT);
hIcon0 = AfxGetApp()->LoadIcon(IDI_SORTA);
ImageList_AddIcon(biSort.himl, hIcon); // Normal
ImageList_AddIcon(biSort.himl, hIcon0); // hot
ImageList_AddIcon(biSort.himl, hIcon); // pushed
ImageList_AddIcon(biSort.himl, hIcon); // disabled
ImageList_AddIcon(biSort.himl, hIcon); // focused
SendDlgItemMessage(IDC_BUTTON1,BCM_SETIMAGELIST, 0, (LPARAM)&biSort);
hUButt=CreateWindow("BUTTON","Up",BS_BITMAP|WS_CHILD,5,5,30, 30,hWnd,NULL,hInstance,NULL);
HBITMAP bmp = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(ID_MYBITMAP)); //загрузка битмапа ID_MYBITMAP из ресурса
SendMessage(hUButt, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) bmp);
#pragma comment(linker, "/ENTRY:wWinMainCRTStartup")
#else
#pragma comment(linker, "/ENTRY:WinMainCRTStartup")
#endif // UNICODE
#include <Windows.h>
#include <WindowsX.h>
#include <TChar.h>
HICON g_hIcon1 = NULL, g_hIcon2 = NULL; // хендлы иконок
HBITMAP g_hBmp1 = NULL, g_hBmp2 = NULL; // хендлы битмапы
HWND g_hWndBtn1 = NULL; // хендл кнопки c иконкой
HWND g_hWndBtn2 = NULL; // хендл кнопки с битмапой
BOOL g_bStateButton1 = FALSE;
BOOL g_bStateButton2 = FALSE;
SIZE SizeBitmap(HBITMAP hBmp) {
SIZE resSize = {0,0};
BITMAP bmp = {0,0,0,0,0,0,NULL};
int iRes = ::GetObject(hBmp, sizeof(BITMAP), &bmp);
if (iRes == sizeof(BITMAP)) {
resSize.cx = bmp.bmWidth;
resSize.cy = bmp.bmHeight;
}
return resSize;
}
SIZE SizeIcon(HICON hIcon) {
SIZE resSize = {0,0};
ICONINFO iconInfo;
if (::GetIconInfo(hIcon, &iconInfo)) {
resSize.cx = iconInfo.xHotspot<<1;
resSize.cy = iconInfo.yHotspot<<1;
}
return resSize;
}
// обработчик сообщения WM_DRAWITEM
void OnDrawItem(HWND hWnd, const DRAWITEMSTRUCT *lpDrawItem) {
//RECT rc = lpDrawItem->rcItem;
//::DrawFrameControl(lpDrawItem->hDC, &rc, DFC_BUTTON, g_bStateButton1 ? DFCS_PUSHED|DFCS_BUTTONPUSH : DFCS_BUTTONPUSH);
if (lpDrawItem->hwndItem == g_hWndBtn1)
{
HICON &hIco = g_bStateButton1 ? g_hIcon1 : g_hIcon2;
BOOL bRes = ::DrawIconEx(
lpDrawItem->hDC,
0,0,
hIco,
lpDrawItem->rcItem.right - lpDrawItem->rcItem.left, lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
0,
NULL,
DI_NORMAL);
}
if (lpDrawItem->hwndItem == g_hWndBtn2)
{
HDC hCDC = ::CreateCompatibleDC(lpDrawItem->hDC);
HBITMAP &hBmp = g_bStateButton2 ? g_hBmp1 : g_hBmp2;
HBITMAP hBmpOld = (HBITMAP)::SelectObject(hCDC, hBmp);
::StretchBlt(
lpDrawItem->hDC,
0,0, lpDrawItem->rcItem.right - lpDrawItem->rcItem.left, lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
hCDC,
0,0, SizeBitmap(hBmp).cx, SizeBitmap(hBmp).cy,
SRCCOPY
);
::SelectObject(hCDC, hBmpOld);
::DeleteDC(hCDC);
}
}
// обработчик клика на кнопку с иконкой
void OnClickButton1() {
g_bStateButton1 = !g_bStateButton1;
::InvalidateRect(g_hWndBtn1, NULL, TRUE);
}
// обработчик клика на кнопку с битмапой
void OnClickButton2() {
g_bStateButton2 = !g_bStateButton2;
::InvalidateRect(g_hWndBtn2, NULL, TRUE);
}
// обработчик сообщения WM_COMMAND
void OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) {
if (hWndCtl == g_hWndBtn1) {
if ((codeNotify == BN_CLICKED) || (codeNotify == BN_DOUBLECLICKED)) {
OnClickButton1();
}
}
if (hWndCtl == g_hWndBtn2) {
if ((codeNotify == BN_CLICKED) || (codeNotify == BN_DOUBLECLICKED)) {
OnClickButton2();
}
}
}
// обработчик сообщения WM_DESTROY
void OnDestroy(HWND hWnd) {
::DestroyIcon(g_hIcon1);
::DestroyIcon(g_hIcon2);
::DeleteObject(g_hBmp1);
::DeleteObject(g_hBmp2);
::PostQuitMessage(0);
}
// Процедра обработки оконных собщений
LRESULT CALLBACK WndProcTest(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
HANDLE_MSG(hWnd, WM_DRAWITEM , OnDrawItem);
HANDLE_MSG(hWnd, WM_DESTROY , OnDestroy );
HANDLE_MSG(hWnd, WM_COMMAND , OnCommand );
//HANDLE_MSG(hWnd, WM_MOUSEMOVE, OnMouseLeave);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// main функция
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow )
{
// создаю главное окно проги
const WNDCLASS wc = {
0, // UINT style
WndProcTest, // WNDPROC lpfnWndProc
0, // int cbClsExtra
0, // int cbWndExtra
hInstance, // HANDLE ghInstance
LoadIcon (NULL, IDI_APPLICATION),// HICON hIcon
LoadCursor(NULL, IDC_ARROW), // HCURSOR hCursor
GetSysColorBrush(COLOR_BTNFACE), // HBRUSH hbrBackground
NULL, // LPCTSTR lpszMenuName
TEXT("ClassWndProject") // LPCTSTR lpszClassName
};
::RegisterClass(&wc);
HWND hWnd = ::CreateWindow( TEXT("ClassWndProject"), TEXT("Test Button Owner Draw"),
WS_OVERLAPPED | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
100, 100, 500, 300, NULL, (HMENU)0, hInstance, NULL );
// создаю кнопку для иконки
g_hWndBtn1 = ::CreateWindow(TEXT("button"), TEXT("пымпочка 1"), WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
20, 20, 100, 30,
hWnd, (HMENU)NULL, hInstance, NULL);
// создаю кнопку для битмапы
g_hWndBtn2 = ::CreateWindow(TEXT("button"), TEXT("пымпочка 2"), WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
20, 60, 100, 30,
hWnd, (HMENU)NULL, hInstance, NULL);
// загружаю рисунки
g_hIcon1 = (HICON) ::LoadImage(hInstance, TEXT("btn1.ico"), IMAGE_ICON , 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
g_hIcon2 = (HICON) ::LoadImage(hInstance, TEXT("btn2.ico"), IMAGE_ICON , 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
g_hBmp1 = (HBITMAP)::LoadImage(hInstance, TEXT("btn1.bmp"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
g_hBmp2 = (HBITMAP)::LoadImage(hInstance, TEXT("btn2.bmp"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
::ShowWindow(hWnd, nCmdShow);
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0)){
::DispatchMessage(&msg);
}
return msg.wParam;
}
Всё очень просто!
}
да, если это просто, то как можно написать посложнее???
да, если это просто, то как можно написать посложнее???
Многословно, зато с комментами, понятно и разбито на функции. Respect!
Многословно, зато с комментами, понятно и разбито на функции. Respect!
Для простой операции вывода картинки на кнопку ты переопределил стандартные обработчики сообщений, ты так отобьешь всякую охоту изучать API :)
#define BCM_SETIMAGELIST (BCM_FIRST + 0x0002)
...
HICON hIcon, hIcon0;
BUTTON_IMAGELIST biSort = { 0 };
biSort.himl = ImageList_Create(20, 20, ILC_COLOR16 | ILC_MASK, 5, 0);
biSort.uAlign = 5;
hIcon = AfxGetApp()->LoadIcon(IDI_SORT);
hIcon0 = AfxGetApp()->LoadIcon(IDI_SORTA);
ImageList_AddIcon(biSort.himl, hIcon); // Normal
ImageList_AddIcon(biSort.himl, hIcon0); // hot
ImageList_AddIcon(biSort.himl, hIcon); // pushed
ImageList_AddIcon(biSort.himl, hIcon); // disabled
ImageList_AddIcon(biSort.himl, hIcon); // focused
SendDlgItemMessage(IDC_BUTTON1,BCM_SETIMAGELIST, 0, (LPARAM)&biSort);
А как использовать BUTTON_IMAGELIST? Через поиск он находится в commctrl.h, но при компиляции возникает ошибка 'Undefined symbol BUTTON_IMAGELIST'
<commctrls.h> включен.
И что такое MFC (<Mfc\afxwin.h>)?
А как использовать BUTTON_IMAGELIST? Через поиск он находится в commctrl.h, но при компиляции возникает ошибка 'Undefined symbol BUTTON_IMAGELIST'
<commctrls.h> включен.
И что такое MFC (<Mfc\afxwin.h>)?
MFC - Microsoft Foundation Class Library - мощная библиотека классов для создания сложных Windows-приложений с богатым графическим интерфейсом.
чтобы не использовать ничего лишнего объяви:
{
HIMAGELIST himl;
RECT margin;
UINT uAlign;
};
#define BCM_SETIMAGELIST (BCM_FIRST + 0x0002)
...
HICON hIcon, hIcon0;
BUTTON_IMAGELIST biSort = { 0 };
biSort.himl = ImageList_Create(20, 20, ILC_COLOR16 | ILC_MASK, 5, 0);
biSort.uAlign = 5;
hIcon = AfxGetApp()->LoadIcon(IDI_SORT);
hIcon0 = AfxGetApp()->LoadIcon(IDI_SORTA);
ImageList_AddIcon(biSort.himl, hIcon); // Normal
ImageList_AddIcon(biSort.himl, hIcon0); // hot
ImageList_AddIcon(biSort.himl, hIcon); // pushed
ImageList_AddIcon(biSort.himl, hIcon); // disabled
ImageList_AddIcon(biSort.himl, hIcon); // focused
SendDlgItemMessage(IDC_BUTTON1,BCM_SETIMAGELIST, 0, (LPARAM)&biSort);
В чем ты работаешь? У меня в ВСВ6 ни в одном из
заголовочных файлов нет ни IDI_SORT, ни IDI_SORTA
(вместо них поставил "имя ресурса"), ни IDI_BUTTON1 -- вместо него не знаю, что ставить
(думаю и пробую, поставил HWND hWndMain).
В прототипе SendDlgMessage у меня на 1 параметр (wParam) больше:
HWND hDlg, // handle of dialog box
int nIDDlgItem, // identifier of control
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
P.S. С компиляцией вроде разобрался, в wParam сунул 32 (это норма:))
Linker error: unresolved external stdcall AfxGetModuleState()
Чево с этим делать не знаю. Не дампить же теперь все Dll,
Bpl и разбираться с динамическими библиотеками, всему свое
время...
В чем ты работаешь? У меня в ВСВ6 ни в одном из
заголовочных файлов нет ни IDI_SORT, ни IDI_SORTA
(вместо них поставил "имя ресурса"), ни IDI_BUTTON1 -- вместо него не знаю, что ставить
(думаю и пробую, поставил HWND hWndMain).
В прототипе SendDlgMessage у меня на 1 параметр (wParam) больше:
HWND hDlg, // handle of dialog box
int nIDDlgItem, // identifier of control
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
P.S. С компиляцией вроде разобрался, в wParam сунул 32 (это норма:))
Linker error: unresolved external stdcall AfxGetModuleState()
Чево с этим делать не знаю. Не дампить же теперь все Dll,
Bpl и разбираться с динамическими библиотеками, всему свое
время...
IDI_SORT, IDI_SORTА - это иконки для вывода на кнопку, находящиеся в ресурсах.
IDI_BUTTON1 - идентификатор кнопки, на которую следует вывести картинку.
Если ты пишешь на Win32API, то в SendDlgItemMessage первым параметром поставь HWND твоего окна
IDI_BUTTON1 - идентификатор кнопки, на которую следует вывести картинку.
Можно, пожалуйста подробнее, что значит 'идентификатор кнопки' и как его получить? И что делать с Unresolved external? AfxGetModuleState() надо каким-то образом подключать? В справке ВСВ об этом ничеко не написано.
IDI_SORT, IDI_SORTА - это иконки для вывода на кнопку, находящиеся в ресурсах.
IDI_BUTTON1 - идентификатор кнопки, на которую следует вывести картинку.
Если ты пишешь на Win32API, то в SendDlgItemMessage первым параметром поставь HWND твоего окна
А как задать идентификатор кнопки, если я не использую ресурсы, а созаю кнопку динамически?
У меня для всех кнопок Id=0
А как задать идентификатор кнопки, если я не использую ресурсы, а созаю кнопку динамически?
У меня для всех кнопок Id=0
А что тебе мешает задать свой идентификатор? Читаем о функции CreateWindow(...), конкретно про параметр hMenu.
А как задать идентификатор кнопки, если я не использую ресурсы, а созаю кнопку динамически?
У меня для всех кнопок Id=0
Можно получить ID через HWND, посмотри MSDN сейчас сказать не могу.
Можно получить ID через HWND, посмотри MSDN сейчас сказать не могу.
Уже разобрался, надо при создании назначить его:)
Уже разобрался, надо при создании назначить его:)
Ты прав на все 100%!