static int winCanvasMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { switch (msg) { case WM_ERASEBKGND: /* only paint background if ACTION is not defined */ if (!IupGetCallback(ih, "ACTION")) { RECT rect; HDC hdc = (HDC)wp; COLORREF color; iupwinGetColorRef(ih, "BGCOLOR", &color); GetClientRect(ih->handle, &rect); FillRect(hdc, &rect, iupwinBrushGet(color)); } else InvalidateRect(ih->handle,NULL,FALSE); /* This will invalidate all area. Necessary in XP, or overlapping windows will have the effect of partial redrawing. */ /* always return non zero value */ *result = 1; return 1; case WM_PAINT: { IFnff cb = (IFnff)IupGetCallback(ih, "ACTION"); if (cb && !(ih->data->inside_resize)) { PAINTSTRUCT ps; HDC hdc = BeginPaint(ih->handle, &ps); iupAttribSet(ih, "HDC_WMPAINT", (char*)hdc); iupAttribSetStrf(ih, "CLIPRECT", "%d %d %d %d", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top); cb(ih, ih->data->posx, ih->data->posy); iupAttribSet(ih, "CLIPRECT", NULL); iupAttribSet(ih, "HDC_WMPAINT", NULL); EndPaint(ih->handle, &ps); } break; } case WM_SIZE: { IFnii cb = (IFnii)IupGetCallback(ih, "RESIZE_CB"); if (cb && !(ih->data->inside_resize)) { /* w=LOWORD (lp), h=HIWORD(lp) can not be used because an invalid size at the first time of WM_SIZE with scroolbars. */ int w, h; RECT rect; GetClientRect(ih->handle, &rect); w = rect.right-rect.left; h = rect.bottom-rect.top; ih->data->inside_resize = 1; /* avoid recursion */ cb(ih, w, h); ih->data->inside_resize = 0; } if (!iupAttribGetBoolean(ih, "MDICLIENT")) { /* If a MDI client, let the DefMDIChildProc do its work. */ *result = 0; return 1; } break; } case WM_GETDLGCODE: /* avoid beeps when keys are pressed */ *result = DLGC_WANTCHARS|DLGC_WANTARROWS; return 1; case WM_MOUSEWHEEL: { IFnfiis cb = (IFnfiis)IupGetCallback(ih, "WHEEL_CB"); short delta = (short)HIWORD(wp); if (cb) { char status[IUPKEY_STATUS_SIZE] = IUPKEY_STATUS_INIT; POINT p; p.x = LOWORD(lp); p.y = HIWORD(lp); ScreenToClient(ih->handle, &p); iupwinButtonKeySetStatus(LOWORD(wp), status, 0); cb(ih, (float)delta/120.0f, p.x, p.y, status); } else { if (ih->data->sb & IUP_SB_VERT) { int i, winop = delta>0? SB_LINEUP: SB_LINEDOWN; delta = (short)abs(delta/120); for (i=0; i < delta; i++) SendMessage(ih->handle, WM_VSCROLL, MAKELONG(winop, 0), 0); } } *result = 0; return 1; } case WM_XBUTTONDBLCLK: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: { /* Force focus on canvas click */ if (iupAttribGetBoolean(ih, "CANFOCUS")) SetFocus(ih->handle); SetCapture(ih->handle); if (iupwinButtonDown(ih, msg, wp, lp)) { /* refresh the cursor, it could have been changed in BUTTON_CB */ SendMessage(ih->handle, WM_SETCURSOR, (WPARAM)ih->handle, MAKELPARAM(1,WM_MOUSEMOVE)); } if (msg==WM_XBUTTONDOWN || msg==WM_XBUTTONDBLCLK) *result = 1; else *result = 0; return 1; } case WM_MOUSEMOVE: { if (iupwinMouseMove(ih, msg, wp, lp)) { /* refresh the cursor, it could have been changed in MOTION_CB */ SendMessage(ih->handle, WM_SETCURSOR, (WPARAM)ih->handle, MAKELPARAM(1,WM_MOUSEMOVE)); } break; /* let iupwinBaseMsgProc process enter/leavewin */ } case WM_XBUTTONUP: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: { ReleaseCapture(); if (iupwinButtonUp(ih, msg, wp, lp)) { /* refresh the cursor, it could have been changed in BUTTON_CB */ SendMessage(ih->handle, WM_SETCURSOR, (WPARAM)ih->handle, MAKELPARAM(1,WM_MOUSEMOVE)); } *result = 0; if (msg==WM_XBUTTONUP) *result = 1; return 1; } case WM_KILLFOCUS: { if (GetCapture() == ih->handle) ReleaseCapture(); break; } case WM_INITMENU: /* abort capture if a menu is opened */ ReleaseCapture(); break; case WM_VSCROLL: /* only process the scrollbar if not a MDI client AND a standard scrollbar */ if (!iupAttribGetBoolean(ih, "MDICLIENT") && lp == 0) { winCanvasProcessVerScroll(ih, LOWORD(wp)); *result = 0; return 1; } case WM_HSCROLL: /* only process the scrollbar if not a MDI client AND a standard scrollbar */ if (!iupAttribGetBoolean(ih, "MDICLIENT") && lp == 0) { winCanvasProcessHorScroll(ih, LOWORD(wp)); *result = 0; return 1; } case WM_SETFOCUS: if (!iupAttribGetBoolean(ih, "CANFOCUS")) { HWND previous = (HWND)wp; if (previous && previous != ih->handle) SetFocus(previous); } break; } /* can be a container */ if (ih->firstchild) return iupwinBaseContainerMsgProc(ih, msg, wp, lp, result); else return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
static int winDialogBaseProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { if (iupwinBaseContainerMsgProc(ih, msg, wp, lp, result)) return 1; iupwinMenuDialogProc(ih, msg, wp, lp); switch (msg) { case WM_GETMINMAXINFO: { if (winDialogCheckMinMaxInfo(ih, (MINMAXINFO*)lp)) { *result = 0; return 1; } break; } case WM_MOVE: { IFnii cb = (IFnii)IupGetCallback(ih, "MOVE_CB"); int x, y; /* ignore LPARAM because they are the clientpos */ iupdrvDialogGetPosition(ih, NULL, &x, &y); if (cb) cb(ih, x, y); break; } case WM_SIZE: { if (ih->data->ignore_resize) break; switch(wp) { case SIZE_MINIMIZED: { if (ih->data->show_state != IUP_MINIMIZE) { IFni show_cb = (IFni)IupGetCallback(ih, "SHOW_CB"); ih->data->show_state = IUP_MINIMIZE; if (show_cb && show_cb(ih, IUP_MINIMIZE) == IUP_CLOSE) IupExitLoop(); } break; } case SIZE_MAXIMIZED: { if (ih->data->show_state != IUP_MAXIMIZE) { IFni show_cb = (IFni)IupGetCallback(ih, "SHOW_CB"); ih->data->show_state = IUP_MAXIMIZE; if (show_cb && show_cb(ih, IUP_MAXIMIZE) == IUP_CLOSE) IupExitLoop(); } winDialogResize(ih, LOWORD(lp), HIWORD(lp)); if (iupAttribGetBoolean(ih, "MDICHILD")) { /* WORKAROUND: when a child MDI dialog is maximized, its title is displayed inside the MDI client area. So we force a MDI client size update */ RECT rect; Ihandle* client = (Ihandle*)iupAttribGet(ih, "MDICLIENT_HANDLE"); GetClientRect(client->handle, &rect); PostMessage(client->handle, WM_SIZE, (WPARAM)SIZE_RESTORED, MAKELPARAM(rect.right-rect.left, rect.bottom-rect.top)); } break; } case SIZE_RESTORED: { if (ih->data->show_state == IUP_MAXIMIZE || ih->data->show_state == IUP_MINIMIZE) { IFni show_cb = (IFni)IupGetCallback(ih, "SHOW_CB"); ih->data->show_state = IUP_RESTORE; if (show_cb && show_cb(ih, IUP_RESTORE) == IUP_CLOSE) IupExitLoop(); } winDialogResize(ih, LOWORD(lp), HIWORD(lp)); break; } } if (iupAttribGetBoolean(ih, "MDIFRAME")) { /* We are going to manually position the MDI client, so abort MDI frame processing. */ *result = 0; return 1; } else break; } case WM_USER+IUPWIN_TRAY_NOTIFICATION: { int dclick = 0; int button = 0; int pressed = 0; switch (lp) { case WM_LBUTTONDOWN: pressed = 1; button = 1; break; case WM_MBUTTONDOWN: pressed = 1; button = 2; break; case WM_RBUTTONDOWN: pressed = 1; button = 3; break; case WM_LBUTTONDBLCLK: dclick = 1; button = 1; break; case WM_MBUTTONDBLCLK: dclick = 1; button = 2; break; case WM_RBUTTONDBLCLK: dclick = 1; button = 3; break; case WM_LBUTTONUP: button = 1; break; case WM_MBUTTONUP: button = 2; break; case WM_RBUTTONUP: button = 3; break; } if (button != 0) { IFniii cb = (IFniii)IupGetCallback(ih, "TRAYCLICK_CB"); if (cb && cb(ih, button, pressed, dclick) == IUP_CLOSE) IupExitLoop(); } break; } case WM_CLOSE: { Icallback cb = IupGetCallback(ih, "CLOSE_CB"); if (cb) { int ret = cb(ih); if (ret == IUP_IGNORE) { *result = 0; return 1; } if (ret == IUP_CLOSE) IupExitLoop(); } /* child mdi is automatically destroyed */ if (iupAttribGetBoolean(ih, "MDICHILD")) IupDestroy(ih); else { if (!winDialogMDICloseChildren(ih)) { *result = 0; return 1; } IupHide(ih); /* IUP default processing */ } *result = 0; return 1; } case WM_COPYDATA: { IFnsi cb = (IFnsi)IupGetCallback(ih, "COPYDATA_CB"); if (cb) { COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lp; char* iup_id = (char*)cds->dwData; /* from SetGlobal("SINGLEINSTANCE") */ if (iup_id && iup_id[0] == 'I' && iup_id[1] == 'U' && iup_id[2] == 'P') { char* data = iupwinStrFromSystem((TCHAR*)cds->lpData); cb(ih, data, (int)strlen(data)+1); } } break; } case WM_ERASEBKGND: { HBITMAP hBitmap = (HBITMAP)iupAttribGet(ih, "_IUPWIN_BACKGROUND_BITMAP"); if (hBitmap) { RECT rect; HDC hdc = (HDC)wp; HBRUSH hBrush = CreatePatternBrush(hBitmap); GetClientRect(ih->handle, &rect); FillRect(hdc, &rect, hBrush); DeleteObject(hBrush); /* return non zero value */ *result = 1; return 1; } else { unsigned char r, g, b; char* color = iupAttribGet(ih, "_IUPWIN_BACKGROUND_COLOR"); if (iupStrToRGB(color, &r, &g, &b)) { RECT rect; HDC hdc = (HDC)wp; SetDCBrushColor(hdc, RGB(r,g,b)); GetClientRect(ih->handle, &rect); FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH)); /* return non zero value */ *result = 1; return 1; } } break; } case WM_DESTROY: { /* Since WM_CLOSE changed the Windows default processing */ /* WM_DESTROY is NOT received by IupDialogs */ /* Except when they are children of other IupDialogs and the parent is destroyed. */ /* So we have to destroy the child dialog. */ /* The application is responsible for destroying the children before this happen. */ IupDestroy(ih); break; } case WM_DPICHANGED: { IupRefresh(ih); break; } } if (msg == (UINT)WM_HELPMSG) { Ihandle* child = NULL; DWORD* struct_ptr = (DWORD*)lp; if (*struct_ptr == sizeof(CHOOSECOLOR)) { CHOOSECOLOR* choosecolor = (CHOOSECOLOR*)lp; child = (Ihandle*)choosecolor->lCustData; } else if (*struct_ptr == sizeof(CHOOSEFONT)) { CHOOSEFONT* choosefont = (CHOOSEFONT*)lp; child = (Ihandle*)choosefont->lCustData; } if (child) { Icallback cb = IupGetCallback(child, "HELP_CB"); if (cb && cb(child) == IUP_CLOSE) EndDialog((HWND)iupAttribGet(child, "HWND"), IDCANCEL); } } return 0; }