Hello everyone,
In my new app I'm trying to make circle-round windows.
Here ye the code:
bool InitRoundButtons(void)
{
/* Register the ROUNDBUTTON class */
WNDCLASS wc = {
CS_OWNDC|CS_NOCLOSE, RoundButtonProc, 0, 0,
hinst /* Globally defined */, NULL, LoadCursor(NULL, IDC_ARROW),
NULL, NULL, "ROUNDBUTTON"
};
return (bool) RegisterClass(&wc);
}
HWND CreateRoundButton(int x, int y, int dm /* Diameter */, HBITMAP hbmp)
{
/* Create one round button with the rb class ("ROUNDBUTTON").
This is actually a round window that looks like a button and acts
like it. The RoundButtonProc handles the messages */
HWND hbttn = CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW,
"ROUNDBUTTON", NULL, WS_POPUP|WS_VISIBLE,
x, y, dm + 5, dm + 5, NULL, NULL, GetVplInst(), NULL);
/* + 5 for the framing */
if (!hbttn) return NULL;
/* Now we'll paint the window */
HRGN hrgn;
HBRUSH hbr;
HDC hdc;
/* Paint the bitmap on circle region */
hrgn = CreateEllipticRgn(x, y, x + dm, y + dm);
hbr = CreatePatternBrush(hbmp);
hdc = GetDC(hbttn);
SelectObject(hdc, hbr);
if (!PaintRgn(hdc, hrgn)) {
DestroyWindow(hbttn);
DeleteObject(hbr);
return NULL;
}
DeleteObject(hbr);
/* Yeah, I should replace this with a call to PaintRoundButton(). Ah, well */
/* Draw its borders */
hbr = CreateSolidBrush(RGB(120, 115, 149)); /* Nice color */
FrameRgn(hdc, hrgn, hbr, 1, 2);
/* Map the window into that circle */
if (SetWindowRgn(hbttn, hrgn, true)) {
return hbttn;
}
DestroyRoundButton(hbttn);
return NULL;
}
void DestroyRoundButton(HWND hbttn)
{
/*** THIS FUNCTION IS NOT COMPLETE YET ***/
/* Delete the window and the GDI handles */
HRGN hrgn = NULL;
GetWindowRgn(hbttn, hrgn);
DeleteObject(hrgn);
DestroyWindow(hbttn);
}
bool PaintRoundButton(HWND hbttn)
{
HRGN hrgn = NULL;
if (GetWindowRgn(hbttn, hrgn)) {
HDC hdc = GetDC(hbttn);
/* Fill the region */
PaintRgn(hdc, hrgn);
/* Draw its borders */
HBRUSH hbr = CreateSolidBrush(RGB(120, 115, 149));
bool ret = FrameRgn(hdc, hrgn, hbr, 1, 2);
DeleteObject(hbr);
return ret;
}
return false;
}
LRESULT CALLBACK RoundButtonProc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam)
{
switch (msg) {
case WM_CREATE:
break;
case WM_PAINT: {
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
/* Paint the button's bitmap */
PaintRoundButton(hwnd);
EndPaint(hwnd, &ps);
break;
}
case WM_CLOSE:
/* DeleteObject() the regions */
DestroyRoundButton(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
return 0;
}
Yeah, the code is messy - although I thought that should work.
Well, it didn't. The following code:
HWND hbttn = CreateRoundButton(5, 5, 104, A_BITMAP);
works fine but if x is like 50 and y too the circle only gets painted half or I can't see it.
I'm probably missing something, but I've searched the Win32 Help manual and MSDN and I can't find any samples... (I'm quite new to extensive GDI programming :mrgreen:).
Any help appreciated!