static int winValMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { (void)lp; switch (msg) { case WM_SETFOCUS: { if (!iupAttribGetBoolean(ih, "CANFOCUS")) { HWND previous = (HWND)wp; if (previous && previous != ih->handle) { SetFocus(previous); *result = 0; return 1; } } break; } case WM_ERASEBKGND: { RECT rect; HDC hDC = (HDC)wp; GetClientRect(ih->handle, &rect); iupwinDrawParentBackground(ih, hDC, &rect); /* return non zero value */ *result = 1; return 1; } case WM_KEYDOWN: case WM_SYSKEYDOWN: { if (iupwinBaseMsgProc(ih, msg, wp, lp, result)==1) return 1; if (GetKeyState(VK_CONTROL) & 0x8000) /* handle Ctrl+Arrows */ { if (wp == VK_UP || wp == VK_LEFT) { winValIncPageValue(ih, -1); *result = 0; return 1; } if (wp == VK_RIGHT || wp == VK_DOWN) { winValIncPageValue(ih, 1); *result = 0; return 1; } } return 0; } } return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
LRESULT CALLBACK iupwinBaseWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { int ret; LRESULT result = 0; IwinMsgProc MsgProc; Ihandle *ih; ih = iupwinHandleGet(hwnd); if (!ih) return DefWindowProc(hwnd, msg, wp, lp); /* should never happen */ /* check if the element defines a custom procedure */ MsgProc = (IwinMsgProc)IupGetCallback(ih, "_IUPWIN_CTRLMSGPROC_CB"); if (MsgProc) ret = MsgProc(ih, msg, wp, lp, &result); else ret = iupwinBaseMsgProc(ih, msg, wp, lp, &result); if (ret) return result; else { /* retrieve the control previous procedure for subclassing */ WNDPROC oldProc = (WNDPROC)IupGetCallback(ih, "_IUPWIN_OLDWNDPROC_CB"); return CallWindowProc(oldProc, hwnd, msg, wp, lp); } }
static int winToggleImageClassicMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { /* Called only when (ih->data->type==IUP_TOGGLE_IMAGE && !iupwin_comctl32ver6 && !ih->data->flat) */ switch (msg) { case WM_MOUSEACTIVATE: if (!winToggleIsActive(ih)) { *result = MA_NOACTIVATEANDEAT; return 1; } break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_ACTIVATE: case WM_SETFOCUS: if (!winToggleIsActive(ih)) { *result = 0; return 1; } break; } if (msg == WM_LBUTTONDOWN) winToggleUpdateImage(ih, 1, 1); else if (msg == WM_LBUTTONUP) winToggleUpdateImage(ih, 1, 0); return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
static int winToggleImageFlatMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { /* Called only when (ih->data->type==IUP_TOGGLE_IMAGE && ih->data->flat) */ switch (msg) { case WM_MOUSELEAVE: iupAttribSet(ih, "_IUPWINTOG_ENTERWIN", NULL); iupdrvRedrawNow(ih); break; case WM_MOUSEMOVE: if (!iupAttribGet(ih, "_IUPWINTOG_ENTERWIN")) { /* this will not affect the process in iupwinBaseMsgProc*/ /* must be called so WM_MOUSELEAVE will be called */ iupwinTrackMouseLeave(ih); iupAttribSet(ih, "_IUPWINTOG_ENTERWIN", "1"); iupdrvRedrawNow(ih); } break; } return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
static int winButtonMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { if (ih->data->type != IUP_BUTTON_TEXT) { /* redraw IMPRESS image if any */ if ((msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) && iupAttribGet(ih, "IMPRESS")) iupdrvRedrawNow(ih); } switch (msg) { case WM_XBUTTONDBLCLK: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: { /* Process BUTTON_CB */ iupwinButtonDown(ih, msg, wp, lp); /* Feedback will NOT be done when not receiving the focus or when in double click */ if ((msg==WM_LBUTTONDOWN && !iupAttribGetBoolean(ih, "CANFOCUS")) || msg==WM_LBUTTONDBLCLK) { iupAttribSet(ih, "_IUPWINBUT_SELECTED", "1"); iupdrvRedrawNow(ih); } break; } case WM_XBUTTONUP: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: { /* Process BUTTON_CB */ iupwinButtonUp(ih, msg, wp, lp); if (msg==WM_LBUTTONUP) { if (iupAttribGet(ih, "_IUPWINBUT_SELECTED")) { iupAttribSet(ih, "_IUPWINBUT_SELECTED", NULL); iupdrvRedrawNow(ih); } /* BN_CLICKED will NOT be notified when not receiving the focus */ if (!iupAttribGetBoolean(ih, "CANFOCUS")) { Icallback cb = IupGetCallback(ih, "ACTION"); if (cb && cb(ih) == IUP_CLOSE) IupExitLoop(); } } if (!iupwinIsVistaOrNew() && iupObjectCheck(ih)) { /* TIPs desapear forever after a button click in XP, so we force an update. */ char* tip = iupAttribGet(ih, "TIP"); if (tip) iupdrvBaseSetTipAttrib(ih, tip); } break; } case WM_KEYDOWN: case WM_SYSKEYDOWN: if (wp==VK_RETURN) { /* enter activates the button */ iupdrvActivate(ih); *result = 0; return 1; /* abort default processing, or the default button will be activated, in this case even if there is a default button, this button must be activated instead. */ } break; case WM_MOUSELEAVE: if (!iupwin_comctl32ver6 && iupAttribGetBoolean(ih, "FLAT")) { iupAttribSet(ih, "_IUPWINBUT_ENTERWIN", NULL); iupdrvRedrawNow(ih); } if (iupAttribGet(ih, "_IUPWINBUT_SELECTED")) { iupAttribSet(ih, "_IUPWINBUT_SELECTED", NULL); iupdrvRedrawNow(ih); } break; case WM_MOUSEMOVE: if (!iupwin_comctl32ver6 && iupAttribGetBoolean(ih, "FLAT")) { if (!iupAttribGet(ih, "_IUPWINBUT_ENTERWIN")) { iupAttribSet(ih, "_IUPWINBUT_ENTERWIN", "1"); iupdrvRedrawNow(ih); } } break; case WM_SETFOCUS: if (!iupAttribGetBoolean(ih, "CANFOCUS")) { HWND previous = (HWND)wp; if (previous && previous != ih->handle) { SetFocus(previous); *result = 0; return 1; } } break; } return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
int iupwinBaseContainerMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result) { /* All messages here are sent to the parent Window, but they are usefull for child controls. */ switch (msg) { case WM_COMMAND: { Ihandle* child = winContainerWmCommandGetIhandle(ih, wp, lp); if (child) { IFwmCommand cb = (IFwmCommand)IupGetCallback(child, "_IUPWIN_COMMAND_CB"); if (cb) cb(child, wp, lp); } break; } case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: { Ihandle* child = iupwinHandleGet((HWND)lp); if (child && winCheckParent(child, ih)) { IFctlColor cb = (IFctlColor)IupGetCallback(child, "_IUPWIN_CTLCOLOR_CB"); if (cb) return cb(child, (HDC)wp, result); } break; } case WM_DRAWITEM: /* for OWNERDRAW controls */ { Ihandle *child; DRAWITEMSTRUCT *drawitem = (LPDRAWITEMSTRUCT)lp; if (!drawitem) break; if (wp == 0) /* a menu */ child = iupwinMenuGetItemHandle((HMENU)drawitem->hwndItem, drawitem->itemID); else { child = iupwinHandleGet(drawitem->hwndItem); if (child && !winCheckParent(child, ih)) child = NULL; } if (child) { IFdrawItem cb = (IFdrawItem)IupGetCallback(child, "_IUPWIN_DRAWITEM_CB"); if (cb) { cb(child, (void*)drawitem); *result = TRUE; return 1; } } break; } case WM_HSCROLL: case WM_VSCROLL: { Ihandle *child = iupwinHandleGet((HWND)lp); if (child && winCheckParent(child, ih)) { IFni cb = (IFni)IupGetCallback(child, "_IUPWIN_CUSTOMSCROLL_CB"); if (cb) cb(child, LOWORD(wp)); } break; } case WM_NOTIFY: /* Currently, the following controls support custom draw functionality: Header, List-view, Rebar, Toolbar, ToolTip, Trackbar, Tree-view. And for Button if using Windows XP Style. */ { Ihandle *child; NMHDR* msg_info = (NMHDR*)lp; if (!msg_info) break; child = iupwinHandleGet(msg_info->hwndFrom); if (child && winCheckParent(child, ih)) { IFnotify cb = (IFnotify)IupGetCallback(child, "_IUPWIN_NOTIFY_CB"); if (cb) { int ret; if (cb(child, (void*)msg_info, &ret)) { *result = (LRESULT)ret; return 1; } } } break; } default: { /* sent to the list parent */ if (msg == WM_DRAGLISTMSG) { DRAGLISTINFO* lpDrag = (DRAGLISTINFO*) lp; Ihandle *child = iupwinHandleGet(lpDrag->hWnd); if (child && winCheckParent(child, ih)) { *result = iupwinListDND(child, lpDrag->uNotification, lpDrag->ptCursor); return 1; } } break; } } return iupwinBaseMsgProc(ih, msg, wp, lp, result); }
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); }