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

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

reference count (window + class objects) rewrite

File size: 11.4 KB
Line 
1/* $Id: windlgmsg.cpp,v 1.9 2001-06-09 14:50:25 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 hwndNext = GetWindow( hwndControl, GW_HWNDNEXT );
173 }
174 }
175 hwndControl = hwndNext;
176 }
177 while (hwndControl != hwnd);
178 }
179 return RetVal;
180}
181/***********************************************************************
182 * DIALOG_FindMsgDestination
183 *
184 * The messages that IsDialogMessage send may not go to the dialog
185 * calling IsDialogMessage if that dialog is a child, and it has the
186 * DS_CONTROL style set.
187 * We propagate up until we hit a that does not have DS_CONTROL, or
188 * whose parent is not a dialog.
189 *
190 * This is undocumented behaviour.
191 */
192static HWND DIALOG_FindMsgDestination( HWND hwndDlg )
193{
194 while (GetWindowLongA(hwndDlg, GWL_STYLE) & DS_CONTROL)
195 {
196 Win32BaseWindow *pParent;
197 HWND hParent = GetParent(hwndDlg);
198 if (!hParent) break;
199
200 pParent = Win32BaseWindow::GetWindowFromHandle(hParent);
201 if (!pParent) break;
202
203 if (!pParent->IsDialog()) {
204 RELEASE_WNDOBJ(pParent);
205 break;
206 }
207 RELEASE_WNDOBJ(pParent);
208 hwndDlg = hParent;
209 }
210
211 return hwndDlg;
212}
213
214/***********************************************************************
215 * DIALOG_IsDialogMessage
216 */
217static BOOL DIALOG_IsDialogMessage( HWND hwndDlg, BOOL *translate, BOOL *dispatch, INT dlgCode, LPMSG msg )
218{
219 *translate = *dispatch = FALSE;
220
221 if (msg->message == WM_PAINT)
222 {
223 /* Apparently, we have to handle this one as well */
224 *dispatch = TRUE;
225 return TRUE;
226 }
227
228 /* Only the key messages get special processing */
229 if ((msg->message != WM_KEYDOWN) &&
230 (msg->message != WM_SYSCHAR) &&
231 (msg->message != WM_CHAR))
232 return FALSE;
233
234 if (dlgCode & DLGC_WANTMESSAGE)
235 {
236 *translate = *dispatch = TRUE;
237 return TRUE;
238 }
239
240 hwndDlg = DIALOG_FindMsgDestination(hwndDlg);
241
242 switch(msg->message)
243 {
244 case WM_KEYDOWN:
245 switch(msg->wParam)
246 {
247 case VK_TAB:
248 if (!(dlgCode & DLGC_WANTTAB))
249 {
250 SendMessageA( hwndDlg, WM_NEXTDLGCTL,
251 (GetKeyState(VK_SHIFT) & 0x8000), 0 );
252 return TRUE;
253 }
254 break;
255
256 case VK_RIGHT:
257 case VK_DOWN:
258 case VK_LEFT:
259 case VK_UP:
260 if (!(dlgCode & DLGC_WANTARROWS))
261 {
262 BOOL fPrevious = (msg->wParam == VK_LEFT || msg->wParam == VK_UP);
263 HWND hwndNext =
264 GetNextDlgGroupItem (hwndDlg, GetFocus(), fPrevious );
265 SendMessageA( hwndDlg, WM_NEXTDLGCTL, hwndNext, 1 );
266 return TRUE;
267 }
268 break;
269
270 case VK_ESCAPE:
271 SendMessageA( hwndDlg, WM_COMMAND, IDCANCEL,
272 (LPARAM)GetDlgItem( hwndDlg, IDCANCEL ) );
273 return TRUE;
274
275 case VK_RETURN:
276 {
277 DWORD dw = SendMessageA( hwndDlg, DM_GETDEFID, 0, 0 );
278 if (HIWORD(dw) == DC_HASDEFID)
279 {
280 SendMessageA( hwndDlg, WM_COMMAND,
281 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
282 (LPARAM)GetDlgItem(hwndDlg, LOWORD(dw)));
283 }
284 else
285 {
286 SendMessageA( hwndDlg, WM_COMMAND, IDOK,
287 (LPARAM)GetDlgItem( hwndDlg, IDOK ) );
288
289 }
290
291 return TRUE;
292 }
293 }
294 *translate = TRUE;
295 break; /* case WM_KEYDOWN */
296
297 case WM_CHAR:
298 if (dlgCode & DLGC_WANTCHARS) break;
299 /* drop through */
300
301 case WM_SYSCHAR:
302 if (DIALOG_IsAccelerator( msg->hwnd, hwndDlg, msg->wParam ))
303 {
304 /* don't translate or dispatch */
305 return TRUE;
306 }
307 break;
308 }
309
310 /* If we get here, the message has not been treated specially */
311 /* and can be sent to its destination window. */
312 *dispatch = TRUE;
313 return TRUE;
314}
315//******************************************************************************
316//******************************************************************************
317BOOL WIN32API IsDialogMessageA( HWND hwndDlg, LPMSG msg)
318{
319 BOOL ret, translate, dispatch;
320 INT dlgCode;
321
322 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd ))
323 return FALSE;
324
325 dlgCode = SendMessageA( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg);
326 ret = DIALOG_IsDialogMessage(hwndDlg,&translate,&dispatch,dlgCode,msg);
327 if (translate) TranslateMessage( msg );
328 if (dispatch) DispatchMessageA( msg );
329
330 return ret;
331}
332//******************************************************************************
333//******************************************************************************
334BOOL WIN32API IsDialogMessageW(HWND hwndDlg, LPMSG msg)
335{
336 BOOL ret, translate, dispatch;
337 INT dlgCode;
338
339 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd ))
340 return FALSE;
341
342 dlgCode = SendMessageW( msg->hwnd, WM_GETDLGCODE, 0, (LPARAM)msg);
343 ret = DIALOG_IsDialogMessage(hwndDlg,&translate,&dispatch,dlgCode,msg);
344 if (translate) TranslateMessage( msg );
345 if (dispatch) DispatchMessageW( msg );
346 return ret;
347}
348//******************************************************************************
349//******************************************************************************
Note: See TracBrowser for help on using the repository browser.