Commit 59fb1303 authored by Sylvain St-Germain's avatar Sylvain St-Germain Committed by Alexandre Julliard

Implementation of the updown buddy windproc subclassing for the

handling of keyboard up and down arrow.
parent 0768424b
......@@ -4,8 +4,6 @@
* Copyright 1997 Dimitrie O. Paun
*
* TODO:
* - subclass the buddy window (in UPDOWN_SetBuddy) to process the
* arrow keys
* - I am not sure about the default values for the Min, Max, Pos
* (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal)
* - I think I do not handle correctly the WS_BORDER style.
......@@ -61,6 +59,8 @@ DEFAULT_DEBUG_CHANNEL(updown)
#define TIMERID1 1
#define TIMERID2 2
#define BUDDY_UPDOWN_HWND "buddyUpDownHWND"
#define BUDDY_SUPERCLASS_WNDPROC "buddySupperClassWndProc"
static int accelIndex = -1;
......@@ -70,6 +70,8 @@ static int accelIndex = -1;
#define UPDOWN_GetInfoPtr(hwnd) ((UPDOWN_INFO *)GetWindowLongA (hwnd,0))
static LRESULT CALLBACK
UPDOWN_Buddy_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/***********************************************************************
* UPDOWN_InBounds
......@@ -353,31 +355,51 @@ static BOOL UPDOWN_SetBuddy (HWND hwnd, HWND hwndBud)
{
UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr (hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
RECT budRect; /* new coord for the buddy */
RECT budRect; /* new coord for the buddy */
int x; /* new x position and width for the up-down */
*infoPtr->szBuddyClass = '\0';
/* Is is a valid bud? */
/* Is it a valid bud? */
if(!IsWindow(hwndBud))
return FALSE;
/* there is already a body assigned */
if ( infoPtr->Buddy )
RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
/* Store buddy window handle */
infoPtr->Buddy = hwndBud;
infoPtr->Buddy = hwndBud;
/* keep upDown ctrl hwnd in a buddy property */
SetPropA( hwndBud, BUDDY_UPDOWN_HWND, hwnd);
/* Store buddy window clas name */
GetClassNameA (hwndBud, infoPtr->szBuddyClass, 40);
memset(infoPtr->szBuddyClass, 0, UPDOWN_BUDDYCLASSNAMELEN);
GetClassNameA (hwndBud, infoPtr->szBuddyClass, UPDOWN_BUDDYCLASSNAMELEN-1);
if(dwStyle & UDS_ARROWKEYS){
FIXME("we need to subclass the buddy to process the arrow keys.\n");
/* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
when we reset the upDown ctrl buddy to another buddy because it is not
good to break the window proc chain. */
/* keep buddy supperclass wndproc in prop instead of in ptr struct
to prevent accessing freed memory */
SetPropA(
hwndBud,
BUDDY_SUPERCLASS_WNDPROC,
(LONG)GetWindowLongA(hwndBud, GWL_WNDPROC) );
/* Assign the buddy wndproc to local wndproc in order to override
keyboard's up and down arrow */
SetWindowLongA(
hwndBud,
GWL_WNDPROC,
(LONG)UPDOWN_Buddy_SubclassProc);
}
/* do we need to do any adjustments? */
if(!(dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)))
return TRUE;
infoPtr->Buddy = hwndBud;
/* Get the rect of the buddy relative to its parent */
GetWindowRect(infoPtr->Buddy, &budRect);
MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy),
......@@ -639,6 +661,9 @@ LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
if(infoPtr->AccelVect)
COMCTL32_Free (infoPtr->AccelVect);
if ( IsWindow(infoPtr->Buddy) ) /* Cleanup */
RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
COMCTL32_Free (infoPtr);
TRACE("UpDown Ctrl destruction, hwnd=%04x\n", hwnd);
......@@ -771,7 +796,6 @@ LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
if (lParam)
UNKNOWN_PARAM(UDM_SETBUDDY, wParam, lParam);
temp = infoPtr->Buddy;
infoPtr->Buddy = wParam;
UPDOWN_SetBuddy (hwnd, wParam);
TRACE("UpDown Ctrl new buddy(%04x), hwnd=%04x\n",
infoPtr->Buddy, hwnd);
......@@ -842,6 +866,53 @@ LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
return 0;
}
/***********************************************************************
* UPDOWN_Buddy_SubclassProc used to handle messages sent to the buddy
* control.
*/
LRESULT CALLBACK
UPDOWN_Buddy_SubclassProc (
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LONG superClassWndProc = GetPropA(hwnd, BUDDY_SUPERCLASS_WNDPROC);
TRACE("hwnd=%04x, wndProc=%d, uMsg=%04x, wParam=%d, lParam=%d\n",
hwnd, (INT)superClassWndProc, uMsg, wParam, (UINT)lParam);
switch (uMsg)
{
case WM_KEYDOWN:
{
if ( ((int)wParam == VK_UP ) || ((int)wParam == VK_DOWN ) )
{
HWND upDownHwnd = GetPropA(hwnd, BUDDY_UPDOWN_HWND);
UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(upDownHwnd);
if (!lstrcmpA (infoPtr->szBuddyClass, "ListBox"))
{
/* if the buddy is a list window, we must update curr index */
INT oldVal = SendMessageA(hwnd, LB_GETCURSEL, 0, 0);
SendMessageA(hwnd, LB_SETCURSEL, oldVal+1, 0);
}
else
{
UPDOWN_GetBuddyInt(upDownHwnd);
UPDOWN_DoAction(upDownHwnd, 1, wParam==VK_UP);
}
break;
}
/* else Fall Through */
}
default:
return CallWindowProcA( (WNDPROC)superClassWndProc, hwnd, uMsg, wParam, lParam);
}
return 0;
}
/***********************************************************************
* UPDOWN_Register [Internal]
......
......@@ -10,6 +10,8 @@
#include "windef.h"
#include "commctrl.h"
#define UPDOWN_BUDDYCLASSNAMELEN 40
typedef struct
{
UINT AccelCount; /* Number of elements in AccelVect */
......@@ -19,7 +21,7 @@ typedef struct
INT MinVal; /* Minimum up-down value */
INT MaxVal; /* Maximum up-down value */
HWND Buddy; /* Handle to the buddy window */
CHAR szBuddyClass[40]; /* Buddy window class name */
CHAR szBuddyClass[UPDOWN_BUDDYCLASSNAMELEN]; /* Buddy window class name */
INT Flags; /* Internal Flags FLAG_* */
} UPDOWN_INFO;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment