Hello, I have been learning how to use the MS WinAPI, but their documentations is extremely vague in a lot of places, without information on the proper use of functions (PHP.NET manages this just fine!).
But anyhoo. When I handle the WM_DRAWITEM message, it SHOULD display an image on the buttons DC. However, it's just displaying a grey box and nothing else, the image is there. And it should load fine.
Just a note, in the WM_PAINT message, I draw a custom window frame (yet to be changed to allow for resizing, however, that's not the point. The point is that this image loads fine, and is in the same directory. And I use the same method for painting it onto the button as well).
I have checked that it is trying to do it. But creating a MessageBox() mid way through the WM_DRAWITEM (it did show up BTW) however, it is not beign drawn.
I do not want to use MFC or anything else like that.
Also, I have scoured the net, and found nothing decent that actually shows you a full example of how to properly use BS_OWNERDRAW and WM_DRAWITEM, with bitmap images.
Here is the code:
#include <Windows.h>
#include "defs.h"
static HWND X_BUTTON;
BOOL IS_HOVERING_HEADER = FALSE;
WNDPROC X_BUTTON_PROC;
static HWND MAIN_WINDOW;
int xSetButtonState(int state, LPDRAWITEMSTRUCT pdis) {
HBITMAP xbmpSource;
HDC hdcSource;
HDC hdcDest;
PAINTSTRUCT ps;
hdcDest = BeginPaint(X_BUTTON, &ps); // Begin paint
hdcSource = CreateCompatibleDC(GetDC(X_BUTTON));
switch(state) {
case ID_BUTTON_STATE_HOVER:
xbmpSource = (HBITMAP)LoadImage(NULL, L"x_button_hover.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SelectObject(hdcSource, xbmpSource);
BitBlt(pdis->hDC, 170, 5, 25, 19, hdcSource, 0, 0, SRCCOPY);
break;
case ID_BUTTON_STATE_NORMAL:
xbmpSource = (HBITMAP)LoadImage(NULL, L"x_button.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SelectObject(hdcSource, xbmpSource);
BitBlt(pdis->hDC, 170, 5, 25, 19, hdcSource, 0, 0, SRCCOPY);
break;
default:
return 0;
break;
}
EndPaint(X_BUTTON, &ps);
DeleteDC(hdcSource);
DeleteDC(hdcDest);
DeleteObject(xbmpSource);
}
LRESULT CALLBACK WinProc(HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
switch(message) {
case WM_MOUSEMOVE:
{
LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
POINT p;
GetCursorPos(&p);
if(p.x > 170 && p.x < 195 && p.y > 5 && p.y < 24) {
xSetButtonState(ID_BUTTON_STATE_HOVER, pdis);
}
break;
}
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
if(pdis->hwndItem == X_BUTTON) {
HDC hdcSource;
HBITMAP xbmpSource;
HDC hdcDest;
hdcDest = BeginPaint(MAIN_WINDOW, &ps); // Begin paint
hdcSource = CreateCompatibleDC(GetDC(0));
xbmpSource = (HBITMAP)LoadImage(NULL, L"x_button.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SelectObject(hdcSource, xbmpSource);
BitBlt(hdcDest, 170, 5, 25, 19, hdcSource, 0, 0, SRCERASE);
EndPaint(MAIN_WINDOW, &ps); // End paint
DeleteDC(hdcSource);
DeleteDC(hdcDest);
DeleteObject(xbmpSource);
}
break;
}
case WM_PAINT:
{
HBITMAP bmpSource;
HDC hdcSource;
HDC hdcDest;
hdcDest = BeginPaint(MAIN_WINDOW, &ps); // Begin paint
hdcSource = CreateCompatibleDC(GetDC(0));
bmpSource = (HBITMAP)LoadImage(NULL, L"window.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SelectObject(hdcSource, bmpSource);
BitBlt(hdcDest, 0, 0, 200, 200, hdcSource, 0, 0, SRCCOPY);
EndPaint(MAIN_WINDOW, &ps); // End paint
DeleteDC(hdcDest);
DeleteDC(hdcSource);
DeleteObject(bmpSource);
break;
}
case WM_CREATE:
{
X_BUTTON = CreateWindow(
L"BUTTON",
L"",
BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
170, 5,
25, 19,
hWindow,
(HMENU) ID_X_BUTTON,
(HINSTANCE) GetWindowLong(hWindow, GWL_HINSTANCE),
NULL
);
break;
}
case WM_CLOSE:
DestroyWindow(hWindow);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWindow, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) {
WNDCLASSEX window;
MSG message;
window.cbSize = sizeof(WNDCLASSEX);
window.cbClsExtra = 0;
window.cbWndExtra = 0;
window.hInstance = hInstance;
window.style = 0;
window.lpszClassName = L"MAIN_CLASS";
window.lpfnWndProc = WinProc;
window.lpszMenuName = NULL;
window.hbrBackground = (HBRUSH) TRANSPARENT;
window.hCursor = LoadCursor(hInstance, IDC_ARROW);
window.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
window.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if(!RegisterClassEx(&window)) {
MessageBox(NULL, L"Could not register window class!", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
MAIN_WINDOW = CreateWindowEx(
NULL,
L"MAIN_CLASS",
L"Styling",
WS_POPUP | WS_VISIBLE | WS_SYSMENU,
50, 50,
200, 200,
NULL,
NULL,
hInstance,
NULL
);
if(MAIN_WINDOW == NULL) {
MessageBox(NULL, L"Could not create window!", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
ShowWindow(MAIN_WINDOW, nCmdShow);
UpdateWindow(MAIN_WINDOW);
while(GetMessage(&message, MAIN_WINDOW, 0, 0) > 0) {
TranslateMessage(&message);
DispatchMessage(&message);
}
return (int) message.wParam;
}
Thanks!
Caelan.