summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--windowspopover/main.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/windowspopover/main.c b/windowspopover/main.c
index c53422c..4ee7b27 100644
--- a/windowspopover/main.c
+++ b/windowspopover/main.c
@@ -33,51 +33,69 @@ HWND popover;
#define ARROWHEIGHT 8
#define ARROWWIDTH 8 /* should be the same for smooth lines */
+HRGN makePopoverRegion(HDC dc, LONG width, LONG height)
+{
+ POINT pt;
+
+ BeginPath(dc);
+ pt.x = 0;
+ pt.y = ARROWHEIGHT;
+ MoveToEx(dc, pt.x, pt.y, NULL);
+ pt.y += height - ARROWHEIGHT;
+ LineTo(dc, pt.x, pt.y);
+ pt.x += width;
+ LineTo(dc, pt.x, pt.y);
+ pt.y -= height - ARROWHEIGHT;
+ LineTo(dc, pt.x, pt.y);
+ pt.x -= (width / 2) - ARROWWIDTH;
+ LineTo(dc, pt.x, pt.y);
+ pt.x -= ARROWWIDTH;
+ pt.y -= ARROWHEIGHT;
+ LineTo(dc, pt.x, pt.y);
+ pt.x -= ARROWWIDTH;
+ pt.y += ARROWHEIGHT;
+ LineTo(dc, pt.x, pt.y);
+ pt.x = 0;
+ LineTo(dc, pt.x, pt.y);
+ EndPath(dc);
+ return PathToRegion(dc);
+}
+
LRESULT CALLBACK popoverproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC dc;
HRGN region;
- POINT pt;
RECT r;
LONG width;
LONG height;
+ WINDOWPOS *wp;
switch (uMsg) {
case WM_NCPAINT:
GetWindowRect(hwnd, &r);
width = r.right - r.left;
height = r.bottom - r.top;
- dc = GetDCEx(hwnd, (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN);
+ dc = GetWindowDC(hwnd);
if (dc == NULL) abort();
- BeginPath(dc);
- r.left = 0; r.top = 0; // everything's in device coordinates
- pt.x = r.left;
- pt.y = r.top + ARROWHEIGHT;
- if (MoveToEx(dc, pt.x, pt.y, NULL) == 0) abort();
- pt.y += height - ARROWHEIGHT;
- if (LineTo(dc, pt.x, pt.y) == 0) abort();
- pt.x += width;
- LineTo(dc, pt.x, pt.y);
- pt.y -= height - ARROWHEIGHT;
- LineTo(dc, pt.x, pt.y);
- pt.x -= (width / 2) - ARROWWIDTH;
- LineTo(dc, pt.x, pt.y);
- pt.x -= ARROWWIDTH;
- pt.y -= ARROWHEIGHT;
- LineTo(dc, pt.x, pt.y);
- pt.x -= ARROWWIDTH;
- pt.y += ARROWHEIGHT;
- LineTo(dc, pt.x, pt.y);
- pt.x = 0;
- LineTo(dc, pt.x, pt.y);
- EndPath(dc);
SetDCBrushColor(dc, RGB(255, 0, 0));
- region = PathToRegion(dc);
+ region = makePopoverRegion(dc, width, height);
FrameRgn(dc, region, GetStockObject(DC_BRUSH), 1, 1);
- SetWindowRgn(hwnd, region, TRUE);
+ DeleteObject(region);
ReleaseDC(hwnd, dc);
return 0;
+ case WM_WINDOWPOSCHANGED:
+ // this must be here; if it's in WM_NCPAINT weird things happen (see http://stackoverflow.com/questions/26288303/why-is-my-client-rectangle-drawing-behaving-bizarrely-pictures-provided-if-i-t)
+ wp = (WINDOWPOS *) lParam;
+ if ((wp->flags & SWP_NOSIZE) == 0) {
+ dc = GetWindowDC(hwnd);
+ if (dc == NULL) abort();
+ region = makePopoverRegion(dc, wp->cx, wp->cy);
+ SetWindowRgn(hwnd, region, TRUE);
+ // don't delete the region; the window manager owns it now
+ ReleaseDC(hwnd, dc);
+ }
+ break; // defer to DefWindowProc()
case WM_NCCALCSIZE:
{
RECT *r = (RECT *) lParam;
@@ -99,6 +117,7 @@ LRESULT CALLBACK popoverproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
dc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &r);
FillRect(dc, &r, GetSysColorBrush(COLOR_ACTIVECAPTION));
+ FrameRect(dc, &r, GetStockPen(WHITE_PEN));
EndPaint(hwnd, &ps);
return 0;
}