source: trunk/src/user32/windlgmsg.cpp@ 6751

Last change on this file since 6751 was 6751, checked in by sandervl, 24 years ago

GetLastActivePopup update + DIALOG_IsAccelerator fix

File size: 11.6 KB
Line 
1/* $Id: windlgmsg.cpp,v 1.10 2001-09-19 09:10:13 sandervl Exp $ */
2/*
3 * Win32 dialog message APIs for OS/2
4 *
5 * Copyright 1999 Sander van Leeuwen (OS/2 port & adaption)
6 *
7 * Based on Corel WINE code (20000317: window\dialog.c)
8 * (Based on Wine code (990815: window\dialog.c))
9 *
10 * Copyright 1993, 1994, 1996 Alexandre Julliard
11 *
12 * TODO: Dialog accelerator
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <os2win.h>
18#include <misc.h>
19#include <string.h>
20#include <ctype.h>
21#include "win32wbase.h"
22#include "win32dlg.h"
23
24#define DBG_LOCALLOG DBG_windlgmsg
25#include "dbglocal.h"
26
27//******************************************************************************
28//******************************************************************************
29LONG WIN32API SendDlgItemMessageA( HWND hwnd, int id, UINT Msg, WPARAM wParam, LPARAM lParam)
30{
31 Win32Dialog *dialog;
32 HWND hwndDlgItem;
33
34 dialog = (Win32Dialog *)Win32BaseWindow::GetWindowFromHandle(hwnd);
35 if(!dialog) {
36 dprintf(("SendDlgItemMessageA, window %x not found", hwnd));
37 return 0;
38 }
39 hwndDlgItem = dialog->getDlgItem(id);
40 RELEASE_WNDOBJ(dialog);
41 if(hwndDlgItem) {
42 return SendMessageA(hwndDlgItem, Msg, wParam, lParam);
43 }
44 return 0;
45}
46//******************************************************************************
47//******************************************************************************
48LONG WIN32API SendDlgItemMessageW( HWND hwnd, int id, UINT Msg, WPARAM wParam, LPARAM lParam)
49{
50 Win32Dialog *dialog;
51 HWND hwndDlgItem;
52
53 dialog = (Win32Dialog *)Win32BaseWindow::GetWindowFromHandle(hwnd);
54 if(!dialog) {
55 dprintf(("SendDlgItemMessageW, window %x not found", hwnd));
56 return 0;
57 }
58 hwndDlgItem = dialog->getDlgItem(id);
59 RELEASE_WNDOBJ(dialog);
60 if(hwndDlgItem) {
61 return SendMessageW(hwndDlgItem, Msg, wParam, lParam);
62 }
63 return 0;
64}
65/***********************************************************************
66 * DIALOG_IsAccelerator
67 */
68static BOOL DIALOG_IsAccelerator( HWND hwnd, HWND hwndDlg, WPARAM vKey )
69{
70 HWND hwndControl = hwnd;
71 HWND hwndNext;
72 Win32BaseWindow *win32wnd;
73 BOOL RetVal = FALSE;
74 INT dlgCode;
75
76 if (vKey == VK_SPACE)
77 {
78 dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 );
79 if (dlgCode & DLGC_BUTTON)
80 {
81 SendMessageA( hwndControl, WM_LBUTTONDOWN, 0, 0);
82 SendMessageA( hwndControl, WM_LBUTTONUP, 0, 0);
83 RetVal = TRUE;
84 }
85 }
86 else
87 {
88 do
89 {
90 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwndControl);
91 if ( (win32wnd != NULL) &&
92 ((win32wnd->getStyle() & (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE) )
93 {
94 dlgCode = SendMessageA( hwndControl, WM_GETDLGCODE, 0, 0 );
95 if (dlgCode & (DLGC_BUTTON | DLGC_STATIC))
96 {
97 INT textLen = win32wnd->GetWindowTextLengthA();
98
99 if (textLen > 0)
100 {
101 /* find the accelerator key */
102 char* text;
103 LPSTR p;
104
105 text = (char*)malloc(textLen+1);
106 win32wnd->GetWindowTextA(text,textLen);
107 p = text - 2;
108 do
109 {
110 p = strchr( p + 2, '&' );
111 }
112 while (p != NULL && p[1] == '&');
113
114 /* and check if it's the one we're looking for */
115 if (p != NULL && toupper( p[1] ) == toupper( vKey ) )
116 {
117 if ((dlgCode & DLGC_STATIC) ||
118 (win32wnd->getStyle() & 0x0f) == BS_GROUPBOX )
119 {
120 /* set focus to the control */
121 SendMessageA( hwndDlg, WM_NEXTDLGCTL,
122 hwndControl, 1);
123 /* and bump it on to next */
124 SendMessageA( hwndDlg, WM_NEXTDLGCTL, 0, 0);
125 }
126 else
127 //TODO: this else part was removed in Wine and above if rules out this possibility (if (dlgCode & (DLGC_BUTTON | DLGC_STATIC)))
128 if (dlgCode & (DLGC_DEFPUSHBUTTON | DLGC_UNDEFPUSHBUTTON))
129 {
130 /* send command message as from the control */
131 SendMessageA( hwndDlg, WM_COMMAND, MAKEWPARAM( LOWORD(win32wnd->getWindowId()), BN_CLICKED ),
132 (LPARAM)hwndControl );
133 }
134 else if (dlgCode & DLGC_BUTTON)
135 {
136 /* send BM_CLICK message to the control */
137 SendMessageA( hwndControl, BM_CLICK, 0, 0 );
138 }
139 RetVal = TRUE;
140 free(text);
141 RELEASE_WNDOBJ(win32wnd);
142 break;
143 }
144 free(text);
145 }
146 }
147 hwndNext = GetWindow( hwndControl, GW_CHILD );
148 }
149 else
150 {
151 hwndNext = 0;
152 }
153 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
154
155 if (!hwndNext)
156 {
157 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
158 }
159 while (!hwndNext)
160 {
161 hwndControl = GetParent( hwndControl );
162 if (hwndControl == hwndDlg)
163 {
164 if(hwnd==hwndDlg){ /* prevent endless loop */
165 hwndNext=hwnd;
166 break;
167 }
168 hwndNext = GetWindow( hwndDlg, GW_CHILD );
169 }
170 else
171 {
172#ifdef __WIN32OS2__
173 if(hwndControl == 0) {
174 dprintf(("WARNING: DIALOG_IsAccelerator %x %x -> hwndControl == 0", hwnd, hwndDlg));
175 return FALSE;
176 }
177#endif
178 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
179 }
180 }
181 hwndControl = hwndNext;
182 }
183 while (hwndControl != hwnd);
184 }
185 return RetVal;
186}
187/***********************************************************************
188 * DIALOG_FindMsgDestination
189 *
190 * The messages that IsDialogMessage send may not go to the dialog
191 * calling IsDialogMessage if that dialog is a child, and it has the
192 * DS_CONTROL style set.
193 * We propagate up until we hit a that does not have DS_CONTROL, or
194 * whose parent is not a dialog.
195 *
196 * This is undocumented behaviour.
197 */
198static HWND DIALOG_FindMsgDestination( HWND hwndDlg )
199{
200 while (GetWindowLongA(hwndDlg, GWL_STYLE) & DS_CONTROL)
201 {
202 Win32BaseWindow *pParent;
203 HWND hParent = GetParent(hwndDlg);
204 if (!hParent) break;
205
206 pParent = Win32BaseWindow::GetWindowFromHandle(hParent);
207 if (!pParent) break;
208
209 if (!pParent->IsDialog()) {
210 RELEASE_WNDOBJ(pParent);
211 break;
212 }
213 RELEASE_WNDOBJ(pParent);
214 hwndDlg = hParent;
215 }
216
217 return hwndDlg;
218}
219
220/***********************************************************************
221 * DIALOG_IsDialogMessage
222 */
223static BOOL DIALOG_IsDialogMessage( HWND hwndDlg, BOOL *translate, BOOL *dispatch, INT dlgCode, LPMSG msg )
224{
225 *translate = *dispatch = FALSE;
226
227 if (msg->message == WM_PAINT)
228 {
229 /* Apparently, we have to handle this one as well */
230 *dispatch = TRUE;
231 return TRUE;
232 }
233
234 /* Only the key messages get special processing */
235 if ((msg->message != WM_KEYDOWN) &&
236 (msg->message != WM_SYSCHAR) &&
237 (msg->message != WM_CHAR))
238 return FALSE;
239
240 if (dlgCode & DLGC_WANTMESSAGE)
241 {
242 *translate = *dispatch = TRUE;
243 return TRUE;
244 }
245
246 hwndDlg = DIALOG_FindMsgDestination(hwndDlg);
247
248 switch(msg->message)
249 {
250 case WM_KEYDOWN:
251 switch(msg->wParam)
252 {
253 case VK_TAB:
254 if (!(dlgCode & DLGC_WANTTAB))
255 {
256 SendMessageA( hwndDlg, WM_NEXTDLGCTL,
257 (GetKeyState(VK_SHIFT) & 0x8000), 0 );
258 return TRUE;
259 }
260 break;
261
262 case VK_RIGHT:
263 case VK_DOWN:
264 case VK_LEFT:
265 case VK_UP:
266 if (!(dlgCode & DLGC_WANTARROWS))
267 {
268 BOOL fPrevious = (msg->wParam == VK_LEFT || msg->wParam == VK_UP);
269 HWND hwndNext =
270 GetNextDlgGroupItem (hwndDlg, GetFocus(), fPrevious );
271 SendMessageA( hwndDlg, WM_NEXTDLGCTL, hwndNext, 1 );
272 return TRUE;
273 }
274 break;
275
276 case VK_ESCAPE:
277 SendMessageA( hwndDlg, WM_COMMAND, IDCANCEL,
278 (LPARAM)GetDlgItem( hwndDlg, IDCANCEL ) );
279 return TRUE;
280
281 case VK_RETURN:
282 {
283 DWORD dw = SendMessageA( hwndDlg, DM_GETDEFID, 0, 0 );
284 if (HIWORD(dw) == DC_HASDEFID)
285 {
286 SendMessageA( hwndDlg, WM_COMMAND,
287 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
288 (LPARAM)GetDlgItem(hwndDlg, LOWORD(dw)));
289 }
290 else
291 {
292 SendMessageA( hwndDlg, WM_COMMAND, IDOK,
293 (LPARAM)GetDlgItem( hwndDlg, IDOK ) );
294
295 }
296
297 return TRUE;
298 }
299 }
300 *translate = TRUE;
301 break; /* case WM_KEYDOWN */
302
303 case WM_CHAR:
304 if (dlgCode & DLGC_WANTCHARS) break;
305 /* drop through */
306
307 case WM_SYSCHAR:
308 if (DIALOG_IsAccelerator( msg->hwnd, hwndDlg, msg->wParam ))
309 {
310 /* don't translate or dispatch */
311 return TRUE;
312 }
313 break;
314 }
315
316 /* If we get here, the message has not been treated specially */
317 /* and can be sent to its destination window. */
318 *dispatch = TRUE;
319 return TRUE;
320}
321//******************************************************************************
322//******************************************************************************
323BOOL WIN32API IsDialogMessageA( HWND hwndDlg, LPMSG msg)
324{
325 BOOL ret, translate, dispatch;
326 INT dlgCode;
327
328 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd ))
329 return FALSE;
330
331 dlgCode = SendMessageA( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg);
332 ret = DIALOG_IsDialogMessage(hwndDlg,&translate,&dispatch,dlgCode,msg);
333 if (translate) TranslateMessage( msg );
334 if (dispatch) DispatchMessageA( msg );
335
336 return ret;
337}
338//******************************************************************************
339//******************************************************************************
340BOOL WIN32API IsDialogMessageW(HWND hwndDlg, LPMSG msg)
341{
342 BOOL ret, translate, dispatch;
343 INT dlgCode;
344
345 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd ))
346 return FALSE;
347
348 dlgCode = SendMessageW( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg);
349 ret = DIALOG_IsDialogMessage(hwndDlg,&translate,&dispatch,dlgCode,msg);
350 if (translate) TranslateMessage( msg );
351 if (dispatch) DispatchMessageW( msg );
352 return ret;
353}
354//******************************************************************************
355//******************************************************************************
Note: See TracBrowser for help on using the repository browser.