Module: wine Branch: master Commit: 2906aaf605e432bdb7d46be33727fe53a525470a URL: http://source.winehq.org/git/wine.git/?a=commit;h=2906aaf605e432bdb7d46be337...
Author: Nikolay Sivov bunglehead@gmail.com Date: Sat Oct 10 21:04:16 2009 +0400
comctl32/monthcal: Process UpDown year control through subclass procedure.
---
dlls/comctl32/monthcal.c | 126 ++++++++++++++++++++++++++++----------- dlls/comctl32/tests/monthcal.c | 23 +++++++ 2 files changed, 113 insertions(+), 36 deletions(-)
diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c index 7697187..fc73537 100644 --- a/dlls/comctl32/monthcal.c +++ b/dlls/comctl32/monthcal.c @@ -128,6 +128,7 @@ typedef struct HWND hwndNotify; /* Window to receive the notifications */ HWND hWndYearEdit; /* Window Handle of edit box to handle years */ HWND hWndYearUpDown;/* Window Handle of updown box to handle years */ + WNDPROC EditWndProc; /* original Edit window procedure */ } MONTHCAL_INFO, *LPMONTHCAL_INFO;
@@ -1355,7 +1356,7 @@ MONTHCAL_GetCurSel(const MONTHCAL_INFO *infoPtr, SYSTEMTIME *curSel)
/* FIXME: if the specified date is not visible, make it visible */ static LRESULT -MONTHCAL_SetCurSel(MONTHCAL_INFO *infoPtr, SYSTEMTIME *curSel) +MONTHCAL_SetCurSel(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *curSel) { TRACE("%p\n", curSel); if(!curSel) return FALSE; @@ -1725,6 +1726,53 @@ MONTHCAL_RButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam) return 0; }
+/*** + * DESCRIPTION: + * Subclassed edit control windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * + */ +static LRESULT CALLBACK EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MONTHCAL_INFO *infoPtr = (MONTHCAL_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0); + + TRACE("(hwnd=%p, uMsg=%x, wParam=%lx, lParam=%lx)\n", + hwnd, uMsg, wParam, lParam); + + switch (uMsg) + { + case WM_GETDLGCODE: + return DLGC_WANTARROWS | DLGC_WANTALLKEYS; + + case WM_DESTROY: + { + WNDPROC editProc = infoPtr->EditWndProc; + infoPtr->EditWndProc = NULL; + SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc); + return CallWindowProcW(editProc, hwnd, uMsg, wParam, lParam); + } + + case WM_KILLFOCUS: + break; + + case WM_KEYDOWN: + if ((VK_ESCAPE == (INT)wParam) || (VK_RETURN == (INT)wParam)) + break; + + default: + return CallWindowProcW(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam); + } + + SendMessageW(infoPtr->hWndYearUpDown, WM_CLOSE, 0, 0); + SendMessageW(hwnd, WM_CLOSE, 0, 0); + return 0; +} + /* creates updown control and edit box */ static void MONTHCAL_EditYear(MONTHCAL_INFO *infoPtr) { @@ -1749,6 +1797,12 @@ static void MONTHCAL_EditYear(MONTHCAL_INFO *infoPtr) MAKELONG(max_allowed_date.wYear, min_allowed_date.wYear)); SendMessageW(infoPtr->hWndYearUpDown, UDM_SETBUDDY, (WPARAM)infoPtr->hWndYearEdit, 0); SendMessageW(infoPtr->hWndYearUpDown, UDM_SETPOS, 0, infoPtr->curSel.wYear); + + /* subclass edit box */ + infoPtr->EditWndProc = (WNDPROC)SetWindowLongPtrW(infoPtr->hWndYearEdit, + GWLP_WNDPROC, (DWORD_PTR)EditWndProc); + + SetFocus(infoPtr->hWndYearEdit); }
static LRESULT @@ -1757,24 +1811,12 @@ MONTHCAL_LButtonDown(MONTHCAL_INFO *infoPtr, LPARAM lParam) MCHITTESTINFO ht; DWORD hit;
- if (infoPtr->hWndYearUpDown) + /* Actually we don't need input focus for calendar, this is used to kill + year updown and its buddy edit box */ + if (IsWindow(infoPtr->hWndYearUpDown)) { - infoPtr->curSel.wYear = SendMessageW(infoPtr->hWndYearUpDown, UDM_SETPOS, 0, 0); - if(!DestroyWindow(infoPtr->hWndYearUpDown)) - { - FIXME("Can't destroy Updown Control\n"); - } - else - infoPtr->hWndYearUpDown = 0; - - if(!DestroyWindow(infoPtr->hWndYearEdit)) - { - FIXME("Can't destroy Updown Control\n"); - } - else - infoPtr->hWndYearEdit = 0; - - InvalidateRect(infoPtr->hwndSelf, NULL, FALSE); + SetFocus(infoPtr->hwndSelf); + return 0; }
SetCapture(infoPtr->hwndSelf); @@ -1899,6 +1941,8 @@ MONTHCAL_LButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam)
SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr);
+ if(!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0; + ht.cbSize = sizeof(MCHITTESTINFO); ht.pt.x = (short)LOWORD(lParam); ht.pt.y = (short)HIWORD(lParam); @@ -2049,21 +2093,6 @@ MONTHCAL_Paint(MONTHCAL_INFO *infoPtr, HDC hdc_paint) return 0; }
- -static LRESULT -MONTHCAL_KillFocus(const MONTHCAL_INFO *infoPtr, HWND hFocusWnd) -{ - TRACE("\n"); - - if (infoPtr->hwndNotify != hFocusWnd) - ShowWindow(infoPtr->hwndSelf, SW_HIDE); - else - InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); - - return 0; -} - - static LRESULT MONTHCAL_SetFocus(const MONTHCAL_INFO *infoPtr) { @@ -2360,6 +2389,31 @@ MONTHCAL_Destroy(MONTHCAL_INFO *infoPtr) return 0; }
+/* + * Handler for WM_NOTIFY messages + */ +static LRESULT +MONTHCAL_Notify(MONTHCAL_INFO *infoPtr, NMHDR *hdr) +{ + /* notification from year edit updown */ + if (hdr->code == UDN_DELTAPOS) + { + NMUPDOWN *nmud = (NMUPDOWN*)hdr; + + if (hdr->hwndFrom == infoPtr->hWndYearUpDown) + { + /* year value limits are set up explicitly after updown creation */ + if ((nmud->iDelta + nmud->iPos) != infoPtr->curSel.wYear) + { + SYSTEMTIME new_date = infoPtr->curSel; + + new_date.wYear = nmud->iDelta + nmud->iPos; + MONTHCAL_SetCurSel(infoPtr, &new_date); + } + } + } + return 0; +}
static LRESULT WINAPI MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -2439,9 +2493,6 @@ MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_GETDLGCODE: return DLGC_WANTARROWS | DLGC_WANTCHARS;
- case WM_KILLFOCUS: - return MONTHCAL_KillFocus(infoPtr, (HWND)wParam); - case WM_RBUTTONUP: return MONTHCAL_RButtonUp(infoPtr, lParam);
@@ -2464,6 +2515,9 @@ MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SIZE: return MONTHCAL_Size(infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
+ case WM_NOTIFY: + return MONTHCAL_Notify(infoPtr, (NMHDR*)lParam); + case WM_CREATE: return MONTHCAL_Create(hwnd, (LPCREATESTRUCTW)lParam);
diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c index 21c171e..d767066 100644 --- a/dlls/comctl32/tests/monthcal.c +++ b/dlls/comctl32/tests/monthcal.c @@ -1647,6 +1647,28 @@ static void test_monthcal_selrange(void) DestroyWindow(hwnd); }
+static void test_killfocus(void) +{ + HWND hwnd; + DWORD style; + + hwnd = create_monthcal_control(0); + + /* make parent invisible */ + style = GetWindowLong(parent_wnd, GWL_STYLE); + SetWindowLong(parent_wnd, GWL_STYLE, style &~ WS_VISIBLE); + + SendMessage(hwnd, WM_KILLFOCUS, (WPARAM)GetDesktopWindow(), 0); + + style = GetWindowLong(hwnd, GWL_STYLE); + ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n"); + + style = GetWindowLong(parent_wnd, GWL_STYLE); + SetWindowLong(parent_wnd, GWL_STYLE, style | WS_VISIBLE); + + DestroyWindow(hwnd); +} + START_TEST(monthcal) { HMODULE hComctl32; @@ -1684,6 +1706,7 @@ START_TEST(monthcal) test_monthcal_size(); test_monthcal_maxselday(); test_monthcal_selrange(); + test_killfocus();
flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(parent_wnd);