]> git.saurik.com Git - wxWidgets.git/blame - src/os2/window.cpp
Fixed wrong positioning of marks and enumerations in lists of wxHTML.
[wxWidgets.git] / src / os2 / window.cpp
CommitLineData
0e320a79
DW
1// Name: windows.cpp
2// Purpose: wxWindow
cdf1e714 3// Author: David Webster
0e320a79 4// Modified by:
cdf1e714 5// Created: 10/12/99
0e320a79 6// RCS-ID: $Id$
cdf1e714 7// Copyright: (c) David Webster
65571936 8// Licence: wxWindows licence
0e320a79
DW
9/////////////////////////////////////////////////////////////////////////////
10
a885d89a 11//
cdf1e714 12// For compilers that support precompilation, includes "wx.h".
a885d89a 13//
cdf1e714 14#include "wx/wxprec.h"
0e320a79 15
849949b1
DW
16#ifndef WX_PRECOMP
17 #define INCL_DOS
18 #define INCL_PM
19 #include <os2.h>
20 #include "wx/window.h"
21 #include "wx/accel.h"
22 #include "wx/setup.h"
23 #include "wx/menu.h"
24 #include "wx/dc.h"
25 #include "wx/dcclient.h"
26 #include "wx/utils.h"
27 #include "wx/app.h"
28 #include "wx/panel.h"
29 #include "wx/layout.h"
1a75e76f
SN
30 #include "wx/checkbox.h"
31 #include "wx/combobox.h"
849949b1
DW
32 #include "wx/dialog.h"
33 #include "wx/frame.h"
34 #include "wx/listbox.h"
35 #include "wx/button.h"
376ef4a1 36 #include "wx/bmpbuttn.h"
849949b1 37 #include "wx/msgdlg.h"
19193a2c 38 #include "wx/scrolwin.h"
a4a16252 39 #include "wx/radiobox.h"
1a75e76f 40 #include "wx/radiobut.h"
a4a16252 41 #include "wx/slider.h"
272ebf16 42 #include "wx/statbox.h"
a4a16252
SN
43 #include "wx/statusbr.h"
44 #include "wx/toolbar.h"
45 #include "wx/settings.h"
849949b1
DW
46 #include <stdio.h>
47#endif
48
49#if wxUSE_OWNER_DRAWN
50 #include "wx/ownerdrw.h"
51#endif
52
53#if wxUSE_DRAG_AND_DROP
54 #include "wx/dnd.h"
55#endif
0e320a79
DW
56
57#include "wx/menuitem.h"
58#include "wx/log.h"
59
cdf1e714
DW
60#include "wx/os2/private.h"
61
849949b1
DW
62#if wxUSE_TOOLTIPS
63 #include "wx/tooltip.h"
0e320a79
DW
64#endif
65
1de4baa3
DW
66#if wxUSE_NOTEBOOK
67 #include "wx/notebook.h"
68#endif
69
849949b1
DW
70#if wxUSE_CARET
71 #include "wx/caret.h"
72#endif // wxUSE_CARET
73
74#include "wx/intl.h"
75#include "wx/log.h"
76
77
78#include "wx/textctrl.h"
79
0e320a79
DW
80#include <string.h>
81
a885d89a
DW
82//
83// Place compiler, OS specific includes here
84//
849949b1 85
a885d89a
DW
86//
87// Standard macros -- these are for OS/2 PM, but most GUI's have something similar
88//
849949b1 89#ifndef GET_X_LPARAM
a885d89a 90//
849949b1 91// SHORT1FROMMP -- LOWORD
a885d89a 92//
849949b1 93 #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp))
a885d89a 94//
849949b1 95// SHORT2FROMMP -- HIWORD
a885d89a 96//
849949b1
DW
97 #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16))
98#endif // GET_X_LPARAM
99
29a99be3
DW
100#ifndef CW_USEDEFAULT
101# define CW_USEDEFAULT ((int)0x80000000)
102#endif
103
a086de98
DW
104#ifndef VK_OEM_1
105 #define VK_OEM_1 0xBA
106 #define VK_OEM_PLUS 0xBB
107 #define VK_OEM_COMMA 0xBC
108 #define VK_OEM_MINUS 0xBD
109 #define VK_OEM_PERIOD 0xBE
110 #define VK_OEM_2 0xBF
111 #define VK_OEM_3 0xC0
112 #define VK_OEM_4 0xDB
113 #define VK_OEM_5 0xDC
114 #define VK_OEM_6 0xDD
115 #define VK_OEM_7 0xDE
116#endif
117
849949b1
DW
118// ---------------------------------------------------------------------------
119// global variables
120// ---------------------------------------------------------------------------
121
a885d89a 122//
19193a2c 123// The last PM message we got (MT-UNSAFE)
a885d89a 124//
61243a51 125QMSG s_currentMsg;
849949b1 126
19193a2c 127#if wxUSE_MENUS_NATIVE
a885d89a 128wxMenu* wxCurrentPopupMenu = NULL;
19193a2c
KB
129#endif // wxUSE_MENUS_NATIVE
130
849949b1
DW
131// ---------------------------------------------------------------------------
132// private functions
133// ---------------------------------------------------------------------------
a885d89a
DW
134
135//
849949b1 136// the window proc for all our windows; most gui's have something similar
a885d89a 137//
f23208ca
DW
138MRESULT EXPENTRY wxWndProc( HWND hWnd
139 ,ULONG message
140 ,MPARAM mp1
141 ,MPARAM mp2
142 );
11e59d47
DW
143
144#ifdef __WXDEBUG__
145 const char *wxGetMessageName(int message);
146#endif //__WXDEBUG__
147
430974f8
DW
148wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin
149 ,short* pnX
150 ,short* pnY
151 );
152void wxRemoveHandleAssociation(wxWindowOS2* pWin);
153void wxAssociateWinWithHandle( HWND hWnd
154 ,wxWindowOS2* pWin
155 );
a885d89a 156wxWindow* wxFindWinFromHandle(WXHWND hWnd);
849949b1 157
a885d89a
DW
158//
159// get the current state of SHIFT/CTRL keys
160//
161static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
162static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
06519806
DW
163
164static wxWindow* gpWinBeingCreated = NULL;
165
849949b1
DW
166// ---------------------------------------------------------------------------
167// event tables
168// ---------------------------------------------------------------------------
0e320a79 169
19193a2c
KB
170// in wxUniv-OS/2 this class is abstract because it doesn't have DoPopupMenu()
171// method
172#ifdef __WXUNIVERSAL__
173 IMPLEMENT_ABSTRACT_CLASS(wxWindowOS2, wxWindowBase)
174#else // __WXPM__
849949b1 175 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
19193a2c 176#endif // __WXUNIVERSAL__/__WXPM__
0e320a79 177
19193a2c 178BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
0367c1c0
DW
179 EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
180 EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
0367c1c0
DW
181 EVT_IDLE(wxWindowOS2::OnIdle)
182 EVT_SET_FOCUS(wxWindowOS2::OnSetFocus)
849949b1 183END_EVENT_TABLE()
0e320a79 184
849949b1
DW
185// ===========================================================================
186// implementation
187// ===========================================================================
0e320a79 188
19193a2c
KB
189// ---------------------------------------------------------------------------
190// wxWindow utility functions
191// ---------------------------------------------------------------------------
192
a885d89a 193//
776d87d5 194// Find an item given the PM Window id
a885d89a 195//
0367c1c0 196wxWindow* wxWindowOS2::FindItem(
a885d89a 197 long lId
776d87d5 198) const
cdf1e714 199{
19193a2c
KB
200#if wxUSE_CONTROLS
201 wxControl* pItem = wxDynamicCast(this, wxControl);
a885d89a
DW
202
203 if (pItem)
204 {
205 //
206 // I it we or one of our "internal" children?
207 //
19193a2c
KB
208 if (pItem->GetId() == lId
209#ifndef __WXUNIVERSAL__
210 || (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)
211#endif
212 )
a885d89a
DW
213 {
214 return pItem;
215 }
216 }
19193a2c 217#endif // wxUSE_CONTROLS
a885d89a 218
2461cfa0 219 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
776d87d5 220
2461cfa0 221 while (current)
cdf1e714 222 {
2461cfa0 223 wxWindow* pChildWin = current->GetData();
a885d89a 224 wxWindow* pWnd = pChildWin->FindItem(lId);
cdf1e714 225
776d87d5
DW
226 if (pWnd)
227 return pWnd;
cdf1e714 228
2461cfa0 229 current = current->GetNext();
cdf1e714 230 }
776d87d5 231 return(NULL);
0367c1c0 232} // end of wxWindowOS2::FindItem
cdf1e714 233
a885d89a 234//
776d87d5 235// Find an item given the PM Window handle
a885d89a 236//
0367c1c0 237wxWindow* wxWindowOS2::FindItemByHWND(
776d87d5
DW
238 WXHWND hWnd
239, bool bControlOnly
240) const
cdf1e714 241{
2461cfa0 242 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
776d87d5 243
2461cfa0 244 while (current)
cdf1e714 245 {
2461cfa0 246 wxWindow* pParent = current->GetData();
cdf1e714 247
a885d89a 248 //
cdf1e714 249 // Do a recursive search.
a885d89a 250 //
776d87d5
DW
251 wxWindow* pWnd = pParent->FindItemByHWND(hWnd);
252
253 if (pWnd)
254 return(pWnd);
cdf1e714 255
19193a2c
KB
256 if (!bControlOnly
257#if wxUSE_CONTROLS
258 || pParent->IsKindOf(CLASSINFO(wxControl))
259#endif // wxUSE_CONTROLS
260 )
cdf1e714 261 {
2461cfa0 262 wxWindow* pItem = current->GetData();
776d87d5
DW
263
264 if (pItem->GetHWND() == hWnd)
265 return(pItem);
cdf1e714
DW
266 else
267 {
776d87d5
DW
268 if (pItem->ContainsHWND(hWnd))
269 return(pItem);
cdf1e714
DW
270 }
271 }
2461cfa0 272 current = current->GetNext();
cdf1e714 273 }
776d87d5 274 return(NULL);
0367c1c0 275} // end of wxWindowOS2::FindItemByHWND
cdf1e714 276
a885d89a 277//
cdf1e714 278// Default command handler
a885d89a 279//
0367c1c0 280bool wxWindowOS2::OS2Command(
776d87d5
DW
281 WXUINT WXUNUSED(uParam)
282, WXWORD WXUNUSED(uId)
283)
cdf1e714 284{
776d87d5 285 return(FALSE);
cdf1e714
DW
286}
287
288// ----------------------------------------------------------------------------
289// constructors and such
290// ----------------------------------------------------------------------------
291
0367c1c0 292void wxWindowOS2::Init()
0e320a79 293{
a885d89a 294 //
849949b1 295 // PM specific
a885d89a 296 //
776d87d5 297 m_bWinCaptured = FALSE;
cdf1e714 298
47df2b8c 299 m_fnOldWndProc = NULL;
3437f881
DW
300 m_bUseCtl3D = FALSE;
301 m_bMouseInWindow = FALSE;
302 m_bLastKeydownProcessed = FALSE;
cfcebdb1 303 m_pChildrenDisabled = NULL;
0e320a79 304
a885d89a 305 //
849949b1 306 // wxWnd
a885d89a 307 //
c8b5f745
DW
308 m_hMenu = 0L;
309 m_hWnd = 0L;
310 m_hWndScrollBarHorz = 0L;
311 m_hWndScrollBarVert = 0L;
0e320a79 312
4a46a5df
DW
313 memset(&m_vWinSwp, '\0', sizeof (SWP));
314
a885d89a
DW
315 //
316 // Pass WM_GETDLGCODE to DefWindowProc()
4a46a5df 317 //
849949b1 318 m_lDlgCode = 0;
0e320a79 319
776d87d5
DW
320 m_nXThumbSize = 0;
321 m_nYThumbSize = 0;
322 m_bBackgroundTransparent = FALSE;
0e320a79 323
a885d89a
DW
324 //
325 // As all windows are created with WS_VISIBLE style...
326 //
849949b1 327 m_isShown = TRUE;
0e320a79 328
cdf1e714 329#if wxUSE_MOUSEEVENT_HACK
776d87d5
DW
330 m_lLastMouseX =
331 m_lLastMouseY = -1;
332 m_nLastMouseEvent = -1;
cdf1e714 333#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 334} // wxWindowOS2::Init
0e320a79 335
a885d89a 336//
849949b1 337// Destructor
a885d89a 338//
0367c1c0 339wxWindowOS2::~wxWindowOS2()
0e320a79 340{
849949b1 341 m_isBeingDeleted = TRUE;
0e320a79 342
1ec46a5b
DW
343 for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
344 {
47df2b8c 345 wxTopLevelWindow* pFrame = wxDynamicCast(pWin, wxTopLevelWindow);
1ec46a5b
DW
346
347 if (pFrame)
348 {
349 if (pFrame->GetLastFocus() == this)
47df2b8c 350 pFrame->SetLastFocus(NULL);
1ec46a5b
DW
351 }
352 }
19193a2c
KB
353
354 DestroyChildren();
355
849949b1
DW
356 if (m_hWnd)
357 {
a885d89a 358 if(!::WinDestroyWindow(GetHWND()))
223d09f6 359 wxLogLastError(wxT("DestroyWindow"));
a885d89a 360 //
849949b1 361 // remove hWnd <-> wxWindow association
a885d89a 362 //
849949b1
DW
363 wxRemoveHandleAssociation(this);
364 }
cfcebdb1 365 delete m_pChildrenDisabled;
0367c1c0 366} // end of wxWindowOS2::~wxWindowOS2
0e320a79 367
19193a2c 368// real construction (Init() must have been called before!)
0367c1c0 369bool wxWindowOS2::Create(
776d87d5
DW
370 wxWindow* pParent
371, wxWindowID vId
372, const wxPoint& rPos
373, const wxSize& rSize
374, long lStyle
375, const wxString& rName
376)
377{
f23208ca 378 HWND hParent = NULLHANDLE;
19193a2c
KB
379 ULONG ulCreateFlags = 0;
380 WXDWORD dwExStyle = 0;
f23208ca 381
776d87d5
DW
382 wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent"));
383
b9b1d6c8
DW
384#if wxUSE_STATBOX
385 //
386 // wxGTK doesn't allow to create controls with static box as the parent so
387 // this will result in a crash when the program is ported to wxGTK - warn
388 // about it
389 //
390 // the correct solution is to create the controls as siblings of the
391 // static box
392 //
393 wxASSERT_MSG( !wxDynamicCast(pParent, wxStaticBox),
394 _T("wxStaticBox can't be used as a window parent!") );
395#endif // wxUSE_STATBOX
396
776d87d5
DW
397 if ( !CreateBase( pParent
398 ,vId
399 ,rPos
400 ,rSize
401 ,lStyle
402 ,wxDefaultValidator
403 ,rName
404 ))
405 return(FALSE);
406
f23208ca
DW
407 if (pParent)
408 {
409 pParent->AddChild(this);
410 hParent = GetWinHwnd(pParent);
cb71578c 411
cb71578c
DW
412 if ( pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
413 pParent->IsKindOf(CLASSINFO(wxScrolledWindow))
414 )
415 ulCreateFlags |= WS_CLIPSIBLINGS;
f23208ca 416 }
776d87d5 417
a885d89a 418 //
f23208ca
DW
419 // Most wxSTYLES are really PM Class specific styles and will be
420 // set in those class create procs. PM's basic windows styles are
421 // very limited.
a885d89a 422 //
cfcebdb1 423 ulCreateFlags |= OS2GetCreateWindowFlags(&dwExStyle);
51c1d535
DW
424
425
19193a2c
KB
426#ifdef __WXUNIVERSAL__
427 // no 3d effects, we draw them ourselves
428 WXDWORD exStyle = 0;
b9b1d6c8 429#endif // !wxUniversal
19193a2c
KB
430 if (lStyle & wxPOPUP_WINDOW)
431 {
19193a2c
KB
432 ulCreateFlags &= ~WS_VISIBLE;
433 m_isShown = FALSE;
434 }
cfcebdb1
DW
435 else
436 {
437 ulCreateFlags |= WS_VISIBLE;
438 }
19193a2c 439
a885d89a 440 //
5d44b24e
DW
441 // Generic OS/2 Windows have no Control Data but other classes
442 // that call OS2Create may have some.
a885d89a 443 //
a23692f0
DW
444 return(OS2Create( (PSZ)wxCanvasClassName
445 ,rName.c_str()
446 ,ulCreateFlags
447 ,rPos
448 ,rSize
449 ,NULL // Control Data
450 ,dwExStyle
451 ,TRUE // Child
452 ));
0367c1c0 453} // end of wxWindowOS2::Create
0e320a79 454
cdf1e714
DW
455// ---------------------------------------------------------------------------
456// basic operations
457// ---------------------------------------------------------------------------
0e320a79 458
0367c1c0 459void wxWindowOS2::SetFocus()
0e320a79 460{
bbdc9a87 461 HWND hWnd = GetHwnd();
19193a2c 462 wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
bbdc9a87
DW
463
464 if (hWnd)
465 ::WinSetFocus(HWND_DESKTOP, hWnd);
0367c1c0 466} // end of wxWindowOS2::SetFocus
0e320a79 467
1cee3f60
DW
468void wxWindowOS2::SetFocusFromKbd()
469{
470 //
471 // Nothing else to do under OS/2
472 //
473 wxWindowBase::SetFocusFromKbd();
474} // end of wxWindowOS2::SetFocus
475
0fe02759 476wxWindow* wxWindowBase::DoFindFocus()
0e320a79 477{
bbdc9a87
DW
478 HWND hWnd = ::WinQueryFocus(HWND_DESKTOP);
479
480 if (hWnd)
481 {
482 return wxFindWinFromHandle((WXHWND)hWnd);
483 }
484 return NULL;
0fe02759 485} // wxWindowBase::DoFindFocus
0e320a79 486
0367c1c0 487bool wxWindowOS2::Enable(
bbdc9a87
DW
488 bool bEnable
489)
0e320a79 490{
bbdc9a87
DW
491 if (!wxWindowBase::Enable(bEnable))
492 return(FALSE);
493
494 HWND hWnd = GetHwnd();
495
496 if ( hWnd )
497 ::WinEnableWindow(hWnd, (BOOL)bEnable);
498
774468bd
DW
499 //
500 // The logic below doesn't apply to the top level windows -- otherwise
501 // showing a modal dialog would result in total greying out (and ungreying
502 // out later) of everything which would be really ugly
503 //
504 if (IsTopLevel())
505 return TRUE;
506
2461cfa0 507 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
bbdc9a87 508
2461cfa0 509 while (node)
bbdc9a87 510 {
2461cfa0 511 wxWindow* pChild = node->GetData();
bbdc9a87 512
cfcebdb1
DW
513 if (bEnable)
514 {
515 //
516 // Enable the child back unless it had been disabled before us
517 //
518 if (!m_pChildrenDisabled || !m_pChildrenDisabled->Find(pChild))
519 pChild->Enable();
520 }
521 else // we're being disabled
522 {
523 if (pChild->IsEnabled())
524 {
525 //
526 // Disable it as children shouldn't stay enabled while the
527 // parent is not
528 //
529 pChild->Disable();
530 }
531 else // child already disabled, remember it
532 {
533 //
534 // Have we created the list of disabled children already?
535 //
536 if (!m_pChildrenDisabled)
537 m_pChildrenDisabled = new wxWindowList;
538 m_pChildrenDisabled->Append(pChild);
539 }
540 }
2461cfa0 541 node = node->GetNext();
bbdc9a87 542 }
cfcebdb1
DW
543 if (bEnable && m_pChildrenDisabled)
544 {
545 //
546 // We don't need this list any more, don't keep unused memory
547 //
548 delete m_pChildrenDisabled;
549 m_pChildrenDisabled = NULL;
550 }
19193a2c 551 return TRUE;
0367c1c0 552} // end of wxWindowOS2::Enable
0e320a79 553
0367c1c0 554bool wxWindowOS2::Show(
bbdc9a87
DW
555 bool bShow
556)
0e320a79 557{
bbdc9a87
DW
558 if (!wxWindowBase::Show(bShow))
559 return(FALSE);
560
561 HWND hWnd = GetHwnd();
562
563 ::WinShowWindow(hWnd, bShow);
564
565 if (bShow)
566 {
a885d89a 567 ::WinSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
bbdc9a87 568 }
19193a2c 569 return TRUE;
0367c1c0 570} // end of wxWindowOS2::Show
0e320a79 571
0367c1c0 572void wxWindowOS2::Raise()
0e320a79 573{
a885d89a 574 ::WinSetWindowPos(GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_ACTIVATE);
0367c1c0 575} // end of wxWindowOS2::Raise
0e320a79 576
0367c1c0 577void wxWindowOS2::Lower()
0e320a79 578{
a885d89a 579 ::WinSetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE);
0367c1c0 580} // end of wxWindowOS2::Lower
0e320a79 581
0367c1c0 582void wxWindowOS2::SetTitle(
bbdc9a87
DW
583 const wxString& rTitle
584)
0e320a79 585{
0fba44b4 586 ::WinSetWindowText(GetHwnd(), (PSZ)rTitle.c_str());
0367c1c0 587} // end of wxWindowOS2::SetTitle
0e320a79 588
0367c1c0 589wxString wxWindowOS2::GetTitle() const
0e320a79 590{
cdf1e714 591 return wxGetWindowText(GetHWND());
0367c1c0 592} // end of wxWindowOS2::GetTitle
0e320a79 593
4116c221 594void wxWindowOS2::DoCaptureMouse()
0e320a79 595{
f38374d0
DW
596 HWND hWnd = GetHwnd();
597
598 if (hWnd && !m_bWinCaptured)
599 {
600 ::WinSetCapture(HWND_DESKTOP, hWnd);
601 m_bWinCaptured = TRUE;
602 }
0367c1c0 603} // end of wxWindowOS2::GetTitle
0e320a79 604
4116c221 605void wxWindowOS2::DoReleaseMouse()
0e320a79 606{
a885d89a 607 if (m_bWinCaptured)
f38374d0
DW
608 {
609 ::WinSetCapture(HWND_DESKTOP, NULLHANDLE);
610 m_bWinCaptured = FALSE;
611 }
0367c1c0 612} // end of wxWindowOS2::ReleaseMouse
0e320a79 613
0367c1c0
DW
614/* static */ wxWindow* wxWindowBase::GetCapture()
615{
616 HWND hwnd = ::WinQueryCapture(HWND_DESKTOP);
617 return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
618} // end of wxWindowBase::GetCapture
619
620bool wxWindowOS2::SetFont(
f38374d0
DW
621 const wxFont& rFont
622)
0e320a79 623{
f38374d0
DW
624 if (!wxWindowBase::SetFont(rFont))
625 {
626 // nothing to do
627 return(FALSE);
628 }
629
630 HWND hWnd = GetHwnd();
631
e3bfcacf
DW
632 wxOS2SetFont( hWnd
633 ,rFont
634 );
cdf1e714 635 return(TRUE);
e3bfcacf 636} // end of wxWindowOS2::SetFont
0e320a79 637
0367c1c0 638bool wxWindowOS2::SetCursor(
f38374d0
DW
639 const wxCursor& rCursor
640) // check if base implementation is OK
0e320a79 641{
f38374d0
DW
642 if ( !wxWindowBase::SetCursor(rCursor))
643 {
644 // no change
645 return FALSE;
646 }
647
19193a2c
KB
648 if ( m_cursor.Ok() ) {
649 HWND hWnd = GetHwnd();
650 POINTL vPoint;
651 RECTL vRect;
f38374d0 652
19193a2c
KB
653 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
654 ::WinQueryWindowRect(hWnd, &vRect);
f38374d0 655
19193a2c
KB
656 if (::WinPtInRect(vHabmain, &vRect, &vPoint) && !wxIsBusy())
657 {
658 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR());
659 }
f38374d0
DW
660 }
661 return TRUE;
0367c1c0 662} // end of wxWindowOS2::SetCursor
0e320a79 663
0367c1c0 664void wxWindowOS2::WarpPointer(
a885d89a
DW
665 int nXPos
666, int nYPos
667)
0e320a79 668{
a885d89a
DW
669 int nX = nXPos;
670 int nY = nYPos;
671 RECTL vRect;
672
673 ::WinQueryWindowRect(GetHwnd(), &vRect);
674 nX += vRect.xLeft;
675 nY += vRect.yBottom;
676
677 ::WinSetPointerPos(HWND_DESKTOP, (LONG)nX, (LONG)(nY));
0367c1c0 678} // end of wxWindowOS2::WarpPointer
0e320a79 679
0e320a79 680
cdf1e714
DW
681// ---------------------------------------------------------------------------
682// scrolling stuff
683// ---------------------------------------------------------------------------
0e320a79 684
0367c1c0 685int wxWindowOS2::GetScrollPos(
05fc6c0a
DW
686 int nOrient
687) const
0e320a79 688{
b7d8f285
DW
689 if (nOrient == wxHORIZONTAL)
690 return((int)::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
691 else
692 return((int)::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
0367c1c0 693} // end of wxWindowOS2::GetScrollPos
0e320a79 694
0367c1c0 695int wxWindowOS2::GetScrollRange(
05fc6c0a
DW
696 int nOrient
697) const
0e320a79 698{
05fc6c0a 699 MRESULT mr;
0e320a79 700
b7d8f285
DW
701 if (nOrient == wxHORIZONTAL)
702 mr = ::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
703 else
704 mr = ::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
05fc6c0a 705 return((int)SHORT2FROMMR(mr));
0367c1c0 706} // end of wxWindowOS2::GetScrollRange
05fc6c0a 707
0367c1c0 708int wxWindowOS2::GetScrollThumb(
05fc6c0a
DW
709 int nOrient
710) const
0e320a79 711{
b7d8f285
DW
712 if (nOrient == wxHORIZONTAL )
713 return m_nXThumbSize;
714 else
715 return m_nYThumbSize;
0367c1c0 716} // end of wxWindowOS2::GetScrollThumb
0e320a79 717
0367c1c0 718void wxWindowOS2::SetScrollPos(
05fc6c0a
DW
719 int nOrient
720, int nPos
19193a2c 721, bool WXUNUSED(bRefresh)
05fc6c0a 722)
0e320a79 723{
b7d8f285
DW
724 if (nOrient == wxHORIZONTAL )
725 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
726 else
727 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
19193a2c 728} // end of wxWindowOS2::SetScrollPos
0e320a79 729
0367c1c0 730void wxWindowOS2::SetScrollbar(
05fc6c0a
DW
731 int nOrient
732, int nPos
733, int nThumbVisible
734, int nRange
19193a2c 735, bool WXUNUSED(bRefresh)
05fc6c0a 736)
0e320a79 737{
45e0dc94 738 HWND hWnd = GetHwnd();
1c84ee88
DW
739 int nOldRange = nRange - nThumbVisible;
740 int nRange1 = nOldRange;
741 int nPageSize = nThumbVisible;
45e0dc94 742
1c84ee88 743 SBCDATA vInfo;
45e0dc94 744 ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT;
b3260bce 745 SWP vSwp;
859e65de 746 SWP vSwpOwner;
45e0dc94
DW
747 HWND hWndParent;
748 HWND hWndClient;
749 wxWindow* pParent = GetParent();
750
751 if (pParent && pParent->IsKindOf(CLASSINFO(wxFrame)))
752 {
753 wxFrame* pFrame;
754
755 pFrame = wxDynamicCast(pParent, wxFrame);
756 hWndParent = pFrame->GetFrame();
757 hWndClient = GetHwndOf(pParent);
758 }
759 else
760 {
761 if (pParent)
762 hWndParent = GetHwndOf(pParent);
763 else
764 hWndParent = GetHwnd();
765 hWndClient = hWndParent;
766 }
767 ::WinQueryWindowPos(hWndClient, &vSwp);
859e65de 768 ::WinQueryWindowPos(hWnd, &vSwpOwner);
1c84ee88 769
1c84ee88 770 if (nPageSize > 1 && nRange > 0)
05fc6c0a 771 {
1c84ee88
DW
772 nRange1 += (nPageSize - 1);
773 }
774
775 vInfo.cb = sizeof(SBCDATA);
776 vInfo.posFirst = 0;
777 vInfo.posLast = (SHORT)nRange1;
778 vInfo.posThumb = nPos;
779
780 if (nOrient == wxHORIZONTAL )
781 {
782 ulStyle |= SBS_HORZ;
c8b5f745 783 if (m_hWndScrollBarHorz == 0L)
1c84ee88 784 {
859e65de
DW
785 //
786 // Since the scrollbars are usually created before the owner is
787 // sized either via an OnSize event directly or via sizers or
788 // layout constraints, we will initially just use the coords of
789 // the parent window (this is usually a frame client window). But
790 // the bars themselves, are children of the parent frame (i.e
791 // siblings of the frame client. The owner, however is the actual
792 // window being scrolled (or at least the one responsible for
793 // handling the scroll events). The owner will be resized later,
794 // as it is usually a child of a top level window, and when that
795 // is done its scrollbars will be resized and repositioned as well.
796 //
45e0dc94 797 m_hWndScrollBarHorz = ::WinCreateWindow( hWndParent
c8b5f745
DW
798 ,WC_SCROLLBAR
799 ,(PSZ)NULL
800 ,ulStyle
45e0dc94
DW
801 ,vSwp.x
802 ,vSwp.y
803 ,vSwp.cx - 20
c8b5f745
DW
804 ,20
805 ,hWnd
806 ,HWND_TOP
626af800 807 ,60000
c8b5f745
DW
808 ,&vInfo
809 ,NULL
810 );
1c84ee88
DW
811 }
812 else
813 {
859e65de
DW
814 //
815 // The owner (the scrolled window) is a child of the Frame's
816 // client window, usually. The scrollbars are children of the
817 // frame, itself, and thus are positioned relative to the frame's
818 // origin, not the frame's client window origin.
819 // The starting x position is the same as the starting x position
820 // of the owner, but in terms of the parent frame.
821 // The starting y position is 20 pels below the origin of the
822 // owner in terms of the parent frame.
823 // The horz bar is the same width as the owner and 20 pels high.
824 //
524d72c4
DW
825 if (nRange1 >= nThumbVisible)
826 {
827 ::WinSetWindowPos( m_hWndScrollBarHorz
828 ,HWND_TOP
829 ,vSwp.x + vSwpOwner.x
830 ,(vSwp.y + vSwpOwner.y) - 20
831 ,vSwpOwner.cx
832 ,20
833 ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER
834 );
835 ::WinSendMsg( m_hWndScrollBarHorz
836 ,SBM_SETSCROLLBAR
837 ,(MPARAM)nPos
838 ,MPFROM2SHORT(0, (SHORT)nRange1)
839 );
840 ::WinSendMsg( m_hWndScrollBarHorz
841 ,SBM_SETTHUMBSIZE
842 ,MPFROM2SHORT( (SHORT)nThumbVisible
843 ,(SHORT)nRange1
844 )
845 ,(MPARAM)0
846 );
847 }
848 else
849 ::WinShowWindow(m_hWndScrollBarHorz, FALSE);
1c84ee88 850 }
05fc6c0a
DW
851 }
852 else
853 {
1c84ee88 854 ulStyle |= SBS_VERT;
c8b5f745 855 if (m_hWndScrollBarVert == 0L)
1c84ee88 856 {
859e65de
DW
857 //
858 // Since the scrollbars are usually created before the owner is
859 // sized either via an OnSize event directly or via sizers or
860 // layout constraints, we will initially just use the coords of
861 // the parent window (this is usually a frame client window). But
862 // the bars themselves, are children of the parent frame (i.e
863 // siblings of the frame client. The owner, however is the actual
864 // window being scrolled (or at least the one responsible for
865 // handling the scroll events). The owner will be resized later,
866 // as it is usually a child of a top level window, and when that
867 // is done its scrollbars will be resized and repositioned as well.
868 //
45e0dc94 869 m_hWndScrollBarVert = ::WinCreateWindow( hWndParent
c8b5f745
DW
870 ,WC_SCROLLBAR
871 ,(PSZ)NULL
872 ,ulStyle
45e0dc94
DW
873 ,vSwp.x + vSwp.cx - 20
874 ,vSwp.y + 20
c8b5f745 875 ,20
45e0dc94 876 ,vSwp.cy - 20
c8b5f745
DW
877 ,hWnd
878 ,HWND_TOP
626af800 879 ,60001
c8b5f745
DW
880 ,&vInfo
881 ,NULL
882 );
1c84ee88
DW
883 }
884 else
885 {
859e65de
DW
886 //
887 // The owner (the scrolled window) is a child of the Frame's
888 // client window, usually. The scrollbars are children of the
889 // frame, itself and thus are positioned relative to the frame's
890 // origin, not the frame's client window's origin.
891 // Thus, the x position will be frame client's x (usually a few
892 // pels inside the parent frame, plus the width of the owner.
893 // Since we may be using sizers or layout constraints for multiple
894 // child scrolled windows, the y position will be the frame client's
895 // y pos plus the scrolled windows y position, yielding the y
896 // position of the scrollbar relative to the parent frame (the vert
897 // scrollbar is on the right and starts at the bottom of the
898 // owner window).
899 // It is 20 pels wide and the same height as the owner.
900 //
524d72c4
DW
901 if (nRange1 >= nThumbVisible)
902 {
903 ::WinSetWindowPos( m_hWndScrollBarVert
904 ,HWND_TOP
905 ,vSwp.x + vSwpOwner.x + vSwpOwner.cx
906 ,vSwp.y + vSwpOwner.y
907 ,20
908 ,vSwpOwner.cy
909 ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
910 );
911 ::WinSendMsg( m_hWndScrollBarVert
912 ,SBM_SETSCROLLBAR
913 ,(MPARAM)nPos
914 ,MPFROM2SHORT(0, (SHORT)nRange1)
915 );
916 ::WinSendMsg( m_hWndScrollBarVert
917 ,SBM_SETTHUMBSIZE
918 ,MPFROM2SHORT( (SHORT)nThumbVisible
919 ,(SHORT)nRange1
920 )
921 ,(MPARAM)0
922 );
923 }
924 else
925 ::WinShowWindow(m_hWndScrollBarVert, FALSE);
1c84ee88 926 }
05fc6c0a
DW
927 m_nYThumbSize = nThumbVisible;
928 }
0367c1c0 929} // end of wxWindowOS2::SetScrollbar
0e320a79 930
0367c1c0 931void wxWindowOS2::ScrollWindow(
05fc6c0a
DW
932 int nDx
933, int nDy
934, const wxRect* pRect
935)
0e320a79 936{
b7d8f285 937 RECTL vRect;
05fc6c0a 938
5d826f60
SN
939 ::WinQueryWindowRect(GetHwnd(), &vRect);
940 int height = vRect.yTop;
05fc6c0a
DW
941 if (pRect)
942 {
b3260bce 943 vRect.xLeft = pRect->x;
5d826f60 944 vRect.yTop = height - pRect->y;
b3260bce 945 vRect.xRight = pRect->x + pRect->width;
5d826f60 946 vRect.yBottom = vRect.yTop - pRect->height;
e661fcd7 947 }
45e0dc94 948 nDy *= -1; // flip the sign of Dy as OS/2 is opposite Windows.
626af800
DW
949 ::WinScrollWindow( GetHwnd()
950 ,(LONG)nDx
951 ,(LONG)nDy
952 ,&vRect
45e0dc94 953 ,&vRect
626af800 954 ,NULL
80a07196
SN
955 ,NULL
956 ,SW_SCROLLCHILDREN | SW_INVALIDATERGN
626af800 957 );
0367c1c0 958} // end of wxWindowOS2::ScrollWindow
0e320a79 959
cdf1e714
DW
960// ---------------------------------------------------------------------------
961// subclassing
962// ---------------------------------------------------------------------------
0e320a79 963
0367c1c0 964void wxWindowOS2::SubclassWin(
c86c44a0
DW
965 WXHWND hWnd
966)
0e320a79 967{
05fc6c0a
DW
968 HWND hwnd = (HWND)hWnd;
969
61243a51 970 wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") );
e58dab20
DW
971 wxAssociateWinWithHandle( hWnd
972 ,(wxWindow*)this
973 );
974 if (!wxCheckWindowWndProc( hWnd
975 ,(WXFARPROC)wxWndProc
976 ))
977 {
978 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
979 }
980 else
981 {
982 m_fnOldWndProc = (WXFARPROC)NULL;
983 }
0367c1c0 984} // end of wxWindowOS2::SubclassWin
0e320a79 985
0367c1c0 986void wxWindowOS2::UnsubclassWin()
0e320a79 987{
c86c44a0 988 //
cdf1e714 989 // Restore old Window proc
c86c44a0 990 //
e604d44b 991 HWND hwnd = GetHWND();
c86c44a0 992
e604d44b 993 if (m_hWnd)
cdf1e714 994 {
61243a51 995 wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") );
0e320a79 996
e604d44b 997 PFNWP fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP);
51c1d535 998
c86c44a0 999 if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc))
cdf1e714 1000 {
c86c44a0
DW
1001 WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc);
1002 m_fnOldWndProc = 0;
cdf1e714
DW
1003 }
1004 }
0367c1c0 1005} // end of wxWindowOS2::UnsubclassWin
0e320a79 1006
5d44b24e
DW
1007bool wxCheckWindowWndProc(
1008 WXHWND hWnd
1009, WXFARPROC fnWndProc
1010)
1011{
1012 static char zBuffer[512];
1013 CLASSINFO vCls;
1014
1015 ::WinQueryClassName((HWND)hWnd, (LONG)512, (PCH)zBuffer);
1016 ::WinQueryClassInfo(wxGetInstance(), (PSZ)zBuffer, &vCls);
1017 return(fnWndProc == (WXFARPROC)vCls.pfnWindowProc);
1018} // end of WinGuiBase_CheckWindowWndProc
1019
b9b1d6c8
DW
1020void wxWindowOS2::SetWindowStyleFlag(
1021 long lFlags
1022)
1023{
1024 long lFlagsOld = GetWindowStyleFlag();
1025
1026 if (lFlags == lFlagsOld)
1027 return;
1028
1029 //
1030 // Update the internal variable
1031 //
1032 wxWindowBase::SetWindowStyleFlag(lFlags);
1033
1034 //
1035 // Now update the Windows style as well if needed - and if the window had
1036 // been already created
1037 //
1038 if (!GetHwnd())
1039 return;
1040
1041 WXDWORD dwExstyle;
1042 WXDWORD dwExstyleOld;
1043 long lStyle = OS2GetStyle( lFlags
1044 ,&dwExstyle
1045 );
1046 long lStyleOld = OS2GetStyle( lFlagsOld
1047 ,&dwExstyleOld
1048 );
1049
1050 if (lStyle != lStyleOld)
1051 {
1052 //
1053 // Some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by
1054 // this function so instead of simply setting the style to the new
1055 // value we clear the bits which were set in styleOld but are set in
1056 // the new one and set the ones which were not set before
1057 //
1058 long lStyleReal = ::WinQueryWindowULong(GetHwnd(), QWL_STYLE);
1059
1060 lStyleReal &= ~lStyleOld;
1061 lStyleReal |= lStyle;
1062
1063 ::WinSetWindowULong(GetHwnd(), QWL_STYLE, lStyleReal);
1064 }
1065} // end of wxWindowOS2::SetWindowStyleFlag
1066
1067WXDWORD wxWindowOS2::OS2GetStyle(
1068 long lFlags
1069, WXDWORD* pdwExstyle
1070) const
1071{
1072 WXDWORD dwStyle = 0L;
1073
1074 if (lFlags & wxCLIP_CHILDREN )
1075 dwStyle |= WS_CLIPCHILDREN;
1076
1077 if (lFlags & wxCLIP_SIBLINGS )
1078 dwStyle |= WS_CLIPSIBLINGS;
1079
1080 return dwStyle;
1081} // end of wxWindowMSW::MSWGetStyle
1082
05fc6c0a 1083//
77ffb593 1084// Make a Windows extended style from the given wxWidgets window style
05fc6c0a 1085//
0367c1c0 1086WXDWORD wxWindowOS2::MakeExtendedStyle(
05fc6c0a
DW
1087 long lStyle
1088, bool bEliminateBorders
1089)
0e320a79 1090{
05fc6c0a 1091 //
008089f6
DW
1092 // Simply fill out with wxWindow extended styles. We'll conjure
1093 // something up in OS2Create and all window redrawing pieces later
05fc6c0a 1094 //
008089f6
DW
1095 WXDWORD dwStyle = 0;
1096
1097 if (lStyle & wxTRANSPARENT_WINDOW )
1098 dwStyle |= wxTRANSPARENT_WINDOW;
1099
1100 if (!bEliminateBorders)
1101 {
1102 if (lStyle & wxSUNKEN_BORDER)
1103 dwStyle |= wxSUNKEN_BORDER;
1104 if (lStyle & wxDOUBLE_BORDER)
1105 dwStyle |= wxDOUBLE_BORDER;
1106 if (lStyle & wxRAISED_BORDER )
1107 dwStyle |= wxRAISED_BORDER;
1108 if (lStyle & wxSTATIC_BORDER)
1109 dwStyle |= wxSTATIC_BORDER;
1110 }
1111 return dwStyle;
0367c1c0 1112} // end of wxWindowOS2::MakeExtendedStyle
cdf1e714 1113
c86c44a0 1114//
cdf1e714 1115// Setup background and foreground colours correctly
c86c44a0 1116//
0367c1c0 1117void wxWindowOS2::SetupColours()
cdf1e714
DW
1118{
1119 if ( GetParent() )
1120 SetBackgroundColour(GetParent()->GetBackgroundColour());
0367c1c0 1121} // end of wxWindowOS2::SetupColours
cdf1e714 1122
0367c1c0 1123void wxWindowOS2::OnIdle(
19193a2c 1124 wxIdleEvent& WXUNUSED(rEvent)
c86c44a0 1125)
cdf1e714 1126{
c86c44a0
DW
1127 //
1128 // Check if we need to send a LEAVE event
1129 //
1130 if (m_bMouseInWindow)
1131 {
1132 POINTL vPoint;
cdf1e714 1133
c86c44a0
DW
1134 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
1135 if (::WinWindowFromPoint(HWND_DESKTOP, &vPoint, FALSE) != (HWND)GetHwnd())
1136 {
1137 //
1138 // Generate a LEAVE event
1139 //
1140 m_bMouseInWindow = FALSE;
1141
1142 //
1143 // Unfortunately the mouse button and keyboard state may have changed
1144 // by the time the OnIdle function is called, so 'state' may be
1145 // meaningless.
1146 //
1147 int nState = 0;
1148
8d902dd6
SN
1149 if (IsShiftDown())
1150 nState |= KC_SHIFT;
1151 if (IsCtrlDown())
1152 nState |= KC_CTRL;
c86c44a0
DW
1153
1154 wxMouseEvent rEvent(wxEVT_LEAVE_WINDOW);
1155
1156 InitMouseEvent( rEvent
1157 ,vPoint.x
1158 ,vPoint.y
1159 ,nState
1160 );
542875a8 1161 (void)GetEventHandler()->ProcessEvent(rEvent);
c86c44a0
DW
1162 }
1163 }
e39af974
JS
1164 if (wxUpdateUIEvent::CanUpdate(this))
1165 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
0367c1c0 1166} // end of wxWindowOS2::OnIdle
c86c44a0
DW
1167
1168//
cdf1e714 1169// Set this window to be the child of 'parent'.
c86c44a0 1170//
0367c1c0 1171bool wxWindowOS2::Reparent(
c86c44a0
DW
1172 wxWindow* pParent
1173)
cdf1e714 1174{
c86c44a0 1175 if (!wxWindowBase::Reparent(pParent))
cdf1e714 1176 return FALSE;
c86c44a0
DW
1177
1178 HWND hWndChild = GetHwnd();
1179 HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
1180
1181 ::WinSetParent(hWndChild, hWndParent, TRUE);
1182 return TRUE;
0367c1c0 1183} // end of wxWindowOS2::Reparent
cdf1e714 1184
06519806
DW
1185void wxWindowOS2::Update()
1186{
1187 ::WinUpdateWindow(GetHwnd());
1188} // end of wxWindowOS2::Update
1189
1190void wxWindowOS2::Freeze()
1191{
1192 ::WinSendMsg(GetHwnd(), WM_VRNDISABLED, (MPARAM)0, (MPARAM)0);
1193} // end of wxWindowOS2::Freeze
1194
1195void wxWindowOS2::Thaw()
1196{
1197 ::WinSendMsg(GetHwnd(), WM_VRNENABLED, (MPARAM)TRUE, (MPARAM)0);
1198
1199 //
1200 // We need to refresh everything or otherwise he invalidated area is not
1201 // repainted.
1202 //
1203 Refresh();
1204} // end of wxWindowOS2::Thaw
1205
0367c1c0 1206void wxWindowOS2::Refresh(
c86c44a0
DW
1207 bool bEraseBack
1208, const wxRect* pRect
1209)
cdf1e714 1210{
c86c44a0
DW
1211 HWND hWnd = GetHwnd();
1212
1213 if (hWnd)
1214 {
1215 if (pRect)
1216 {
1217 RECTL vOs2Rect;
5d826f60 1218 int height;
c86c44a0 1219
5d826f60
SN
1220 ::WinQueryWindowRect(GetHwnd(), &vOs2Rect);
1221 height = vOs2Rect.yTop;
c86c44a0 1222 vOs2Rect.xLeft = pRect->x;
5d826f60 1223 vOs2Rect.yTop = height - pRect->y;
c86c44a0 1224 vOs2Rect.xRight = pRect->x + pRect->width;
5d826f60 1225 vOs2Rect.yBottom = vOs2Rect.yTop - pRect->height;
c86c44a0
DW
1226
1227 ::WinInvalidateRect(hWnd, &vOs2Rect, bEraseBack);
1228 }
1229 else
1230 ::WinInvalidateRect(hWnd, NULL, bEraseBack);
45e0dc94
DW
1231 if (m_hWndScrollBarHorz != NULLHANDLE)
1232 ::WinInvalidateRect(m_hWndScrollBarHorz, NULL, TRUE);
1233 if (m_hWndScrollBarVert != NULLHANDLE)
1234 ::WinInvalidateRect(m_hWndScrollBarVert, NULL, TRUE);
c86c44a0 1235 }
0367c1c0 1236} // end of wxWindowOS2::Refresh
cdf1e714
DW
1237
1238// ---------------------------------------------------------------------------
1239// drag and drop
1240// ---------------------------------------------------------------------------
1241
1242#if wxUSE_DRAG_AND_DROP
0367c1c0 1243void wxWindowOS2::SetDropTarget(
c86c44a0
DW
1244 wxDropTarget* pDropTarget
1245)
cdf1e714 1246{
c86c44a0 1247 m_dropTarget = pDropTarget;
0367c1c0 1248} // end of wxWindowOS2::SetDropTarget
cdf1e714
DW
1249#endif
1250
c86c44a0 1251//
cdf1e714
DW
1252// old style file-manager drag&drop support: we retain the old-style
1253// DragAcceptFiles in parallel with SetDropTarget.
c86c44a0 1254//
0367c1c0 1255void wxWindowOS2::DragAcceptFiles(
c86c44a0
DW
1256 bool bAccept
1257)
cdf1e714 1258{
c86c44a0
DW
1259 HWND hWnd = GetHwnd();
1260
1261 if (hWnd && bAccept)
542875a8 1262 ::DrgAcceptDroppedFiles(hWnd, NULL, NULL, DO_COPY, 0L);
0367c1c0 1263} // end of wxWindowOS2::DragAcceptFiles
cdf1e714
DW
1264
1265// ----------------------------------------------------------------------------
1266// tooltips
1267// ----------------------------------------------------------------------------
1268
1269#if wxUSE_TOOLTIPS
1270
0367c1c0 1271void wxWindowOS2::DoSetToolTip(
c86c44a0
DW
1272 wxToolTip* pTooltip
1273)
cdf1e714 1274{
c86c44a0 1275 wxWindowBase::DoSetToolTip(pTooltip);
cdf1e714 1276
542875a8 1277 if (m_tooltip)
cdf1e714 1278 m_tooltip->SetWindow(this);
0367c1c0 1279} // end of wxWindowOS2::DoSetToolTip
cdf1e714
DW
1280
1281#endif // wxUSE_TOOLTIPS
1282
1283// ---------------------------------------------------------------------------
1284// moving and resizing
1285// ---------------------------------------------------------------------------
1286
1287// Get total size
0367c1c0 1288void wxWindowOS2::DoGetSize(
a7ef993c
DW
1289 int* pWidth
1290, int* pHeight
1291) const
cdf1e714 1292{
5d44b24e 1293 HWND hWnd;
a7ef993c 1294 RECTL vRect;
c86c44a0 1295
5d44b24e
DW
1296 if (IsKindOf(CLASSINFO(wxFrame)))
1297 {
1298 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1299 hWnd = pFrame->GetFrame();
1300 }
1301 else
1302 hWnd = GetHwnd();
1303
a7ef993c
DW
1304 ::WinQueryWindowRect(hWnd, &vRect);
1305
1306 if (pWidth)
1307 *pWidth = vRect.xRight - vRect.xLeft;
1308 if (pHeight )
1309 // OS/2 PM is backwards from windows
1310 *pHeight = vRect.yTop - vRect.yBottom;
0367c1c0 1311} // end of wxWindowOS2::DoGetSize
cdf1e714 1312
0367c1c0 1313void wxWindowOS2::DoGetPosition(
a7ef993c
DW
1314 int* pX
1315, int* pY
1316) const
cdf1e714 1317{
a7ef993c 1318 HWND hWnd = GetHwnd();
8330166c 1319 SWP vSwp;
a7ef993c 1320 POINTL vPoint;
8330166c 1321 wxWindow* pParent = GetParent();
c86c44a0 1322
8330166c
DW
1323 //
1324 // It would seem that WinQueryWindowRect would be the correlary to
1325 // the WIN32 WinGetRect, but unlike WinGetRect which returns the window
1326 // origin position in screen coordinates, WinQueryWindowRect returns it
1327 // relative to itself, i.e. (0,0). To get the same under PM we must
1328 // us WinQueryWindowPos. This call, unlike the WIN32 call, however,
1329 // returns a position relative to it's parent, so no parent adujstments
1330 // are needed under OS/2. Also, windows should be created using
1331 // wxWindow coordinates, i.e 0,0 is the TOP left so vSwp will already
1332 // reflect that.
1333 //
1334 ::WinQueryWindowPos(hWnd, &vSwp);
c86c44a0 1335
8330166c
DW
1336 vPoint.x = vSwp.x;
1337 vPoint.y = vSwp.y;
c86c44a0 1338
a7ef993c 1339 //
8330166c
DW
1340 // We may be faking the client origin. So a window that's really at (0,
1341 // 30) may appear (to wxWin apps) to be at (0, 0).
a7ef993c 1342 //
8330166c 1343 if (pParent)
c86c44a0 1344 {
8330166c 1345 wxPoint vPt(pParent->GetClientAreaOrigin());
a7ef993c 1346
8330166c
DW
1347 vPoint.x -= vPt.x;
1348 vPoint.y -= vPt.y;
c86c44a0
DW
1349 }
1350
a7ef993c
DW
1351 if (pX)
1352 *pX = vPoint.x;
542875a8 1353 if (pY)
a7ef993c 1354 *pY = vPoint.y;
0367c1c0 1355} // end of wxWindowOS2::DoGetPosition
cdf1e714 1356
0367c1c0 1357void wxWindowOS2::DoScreenToClient(
a7ef993c
DW
1358 int* pX
1359, int* pY
1360) const
cdf1e714 1361{
a7ef993c 1362 HWND hWnd = GetHwnd();
8330166c 1363 SWP vSwp;
542875a8 1364
8330166c 1365 ::WinQueryWindowPos(hWnd, &vSwp);
cdf1e714 1366
a7ef993c 1367 if (pX)
8330166c 1368 *pX += vSwp.x;
a7ef993c 1369 if (pY)
8330166c 1370 *pY += vSwp.y;
0367c1c0 1371} // end of wxWindowOS2::DoScreenToClient
a7ef993c 1372
0367c1c0 1373void wxWindowOS2::DoClientToScreen(
a7ef993c
DW
1374 int* pX
1375, int* pY
1376) const
cdf1e714 1377{
a7ef993c 1378 HWND hWnd = GetHwnd();
8330166c 1379 SWP vSwp;
19193a2c 1380
8330166c 1381 ::WinQueryWindowPos(hWnd, &vSwp);
c86c44a0 1382
a7ef993c 1383 if (pX)
8330166c 1384 *pX += vSwp.x;
a7ef993c 1385 if (pY)
8330166c 1386 *pY += vSwp.y;
0367c1c0 1387} // end of wxWindowOS2::DoClientToScreen
cdf1e714 1388
a7ef993c 1389//
cdf1e714 1390// Get size *available for subwindows* i.e. excluding menu bar etc.
a7ef993c
DW
1391// Must be a frame type window
1392//
0367c1c0 1393void wxWindowOS2::DoGetClientSize(
a7ef993c
DW
1394 int* pWidth
1395, int* pHeight
1396) const
cdf1e714 1397{
a7ef993c 1398 HWND hWnd = GetHwnd();
a7ef993c
DW
1399 RECTL vRect;
1400
5d44b24e 1401 ::WinQueryWindowRect(hWnd, &vRect);
e37db699
DW
1402 if (IsKindOf(CLASSINFO(wxDialog)))
1403 {
1404 RECTL vTitle;
1405 HWND hWndTitle;
1406 //
1407 // For a Dialog we have to explicitly request the client portion.
1408 // For a Frame the hWnd IS the client window
1409 //
1410 hWndTitle = ::WinWindowFromID(hWnd, FID_TITLEBAR);
1411 if (::WinQueryWindowRect(hWndTitle, &vTitle))
1412 {
1413 if (vTitle.yTop - vTitle.yBottom == 0)
1414 {
1415 //
1416 // Dialog has not been created yet, use a default
1417 //
1418 vTitle.yTop = 20;
1419 }
1420 vRect.yTop -= (vTitle.yTop - vTitle.yBottom);
1421 }
1422
1423 ULONG uStyle = ::WinQueryWindowULong(hWnd, QWL_STYLE);
1424
1425 //
1426 // Deal with borders
1427 //
1428 if (uStyle & FCF_DLGBORDER)
1429 {
1430 vRect.xLeft += 4;
1431 vRect.xRight -= 4;
1432 vRect.yTop -= 4;
1433 vRect.yBottom += 4;
1434 }
1435 else if (uStyle & FCF_SIZEBORDER)
1436 {
1437 vRect.xLeft += 4;
1438 vRect.xRight -= 4;
1439 vRect.yTop -= 4;
1440 vRect.yBottom += 4;
1441 }
1442 else if (uStyle & FCF_BORDER)
1443 {
1444 vRect.xLeft += 2;
1445 vRect.xRight -= 2;
1446 vRect.yTop -= 2;
1447 vRect.yBottom += 2;
1448 }
1449 else // make some kind of adjustment or top sizers ram into the titlebar!
1450 {
1451 vRect.xLeft += 3;
1452 vRect.xRight -= 3;
1453 vRect.yTop -= 3;
1454 vRect.yBottom += 3;
1455 }
1456 }
542875a8 1457 if (pWidth)
e37db699 1458 *pWidth = vRect.xRight - vRect.xLeft;
542875a8 1459 if (pHeight)
e37db699 1460 *pHeight = vRect.yTop - vRect.yBottom;
0367c1c0 1461} // end of wxWindowOS2::DoGetClientSize
cdf1e714 1462
0367c1c0 1463void wxWindowOS2::DoMoveWindow(
a7ef993c
DW
1464 int nX
1465, int nY
1466, int nWidth
1467, int nHeight
1468)
cdf1e714 1469{
39c26ef2 1470 RECTL vRect;
39c26ef2
DW
1471 wxWindow* pParent = GetParent();
1472
9e705092
SN
1473 /* Due to OS/2's inverted coordinate system, changing the height
1474 of a window requires repositioning all it's children, e.g. if
1475 you want a child of height 100 to be at the top left corner of
1476 the parent you need to position the lower left corner of the
1477 child at (0, (height of parent - 100)), so, obviously, if the
1478 height of the parent changes, the child needs to be repositioned. */
1479 int nHeightDelta;
1480 GetSize(0, &nHeightDelta);
1481 nHeightDelta = nHeight - nHeightDelta;
1482
1b086de1 1483 if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
987da0d4 1484 {
d8a3f66c
DW
1485 int nOS2Height = GetOS2ParentHeight(pParent);
1486
1487 nY = nOS2Height - (nY + nHeight);
987da0d4 1488 }
39c26ef2 1489 else
c86c44a0 1490 {
987da0d4
DW
1491 RECTL vRect;
1492
1493 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
1494 nY = vRect.yTop - (nY + nHeight);
1495 }
f289196b
DW
1496
1497 //
1498 // In the case of a frame whose client is sized, the client cannot be
1499 // large than its parent frame minus its borders! This usually happens
1500 // when using an autosizer to size a frame to precisely hold client
1501 // controls as in the notebook sample.
1502 //
1503 // In this case, we may need to resize both a frame and its client so we
1504 // need a quick calc of the frame border size, then if the frame
1505 // (less its borders) is smaller than the client, size the frame to
1506 // encompass the client with the appropriate border size.
1507 //
1508 if (IsKindOf(CLASSINFO(wxFrame)))
1509 {
1510 RECTL vFRect;
1511 HWND hWndFrame;
1512 int nWidthFrameDelta = 0;
1513 int nHeightFrameDelta = 0;
1514 int nHeightFrame = 0;
1515 int nWidthFrame = 0;
f289196b
DW
1516 wxFrame* pFrame;
1517
1518 pFrame = wxDynamicCast(this, wxFrame);
1519 hWndFrame = pFrame->GetFrame();
1520 ::WinQueryWindowRect(hWndFrame, &vRect);
1521 ::WinMapWindowPoints(hWndFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
1522 vFRect = vRect;
1523 ::WinCalcFrameRect(hWndFrame, &vRect, TRUE);
1524 nWidthFrameDelta = ((vRect.xLeft - vFRect.xLeft) + (vFRect.xRight - vRect.xRight));
1525 nHeightFrameDelta = ((vRect.yBottom - vFRect.yBottom) + (vFRect.yTop - vRect.yTop));
1526 nWidthFrame = vFRect.xRight - vFRect.xLeft;
1527 nHeightFrame = vFRect.yTop - vFRect.yBottom;
1528
1529 if (nWidth == vFRect.xRight - vFRect.xLeft &&
1530 nHeight == vFRect.yTop - vFRect.yBottom)
1531 {
1532 //
1533 // In this case the caller is not aware of OS/2's need to size both
1534 // the frame and it's client and is really only moving the window,
1535 // not resizeing it. So move the frame, and back off the sizes
1536 // for a proper client fit.
1537 //
1538 ::WinSetWindowPos( hWndFrame
1539 ,HWND_TOP
1540 ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
1541 ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
1542 ,(LONG)0
1543 ,(LONG)0
1544 ,SWP_MOVE
1545 );
1546 nX += (vRect.xLeft - vFRect.xLeft);
1547 nY += (vRect.yBottom - vFRect.yBottom);
1548 nWidth -= nWidthFrameDelta;
1549 nHeight -= nHeightFrameDelta;
1550 }
1551 else
1552 {
1553 if (nWidth > nWidthFrame - nHeightFrameDelta ||
1554 nHeight > nHeightFrame - nHeightFrameDelta)
1555 {
1556 ::WinSetWindowPos( hWndFrame
1557 ,HWND_TOP
1558 ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
1559 ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
1560 ,(LONG)nWidth + nWidthFrameDelta
1561 ,(LONG)nHeight + nHeightFrameDelta
1562 ,SWP_MOVE | SWP_SIZE
1563 );
1564 }
1565 }
1566 }
1567
987da0d4
DW
1568 ::WinSetWindowPos( GetHwnd()
1569 ,HWND_TOP
1570 ,(LONG)nX
1571 ,(LONG)nY
1572 ,(LONG)nWidth
1573 ,(LONG)nHeight
f289196b 1574 ,SWP_SIZE | SWP_MOVE
987da0d4 1575 );
859e65de
DW
1576 if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0)
1577 //
1578 // Uninitialized
1579 //
1580 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1581 else
1582 {
1583 int nYDiff = m_vWinSwp.cy - nHeight;
1584
1585 //
1586 // Handle resizing of scrolled windows. The target or window to
1587 // be scrolled is the owner (gets the scroll notificaitons). The
1588 // parent is usually the parent frame of the scrolled panel window.
1589 // In order to show the scrollbars the target window will be shrunk
1590 // by the size of the scroll bar widths (20) and moved in the X and Y
1591 // directon. That value will be computed as part of the diff for
1592 // moving the children. Everytime the window is sized the
1593 // toplevel OnSize is going to resize the panel to fit the client
1594 // or the whole sizer and will need to me resized. This will send
1595 // a WM_SIZE out which will be intercepted by the ScrollHelper
1596 // which will cause the scrollbars to be displayed via the SetScrollbar
1597 // call in CWindow.
1598 //
4a46a5df
DW
1599 if ( IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
1600 IsKindOf(CLASSINFO(wxScrolledWindow))
859e65de
DW
1601 )
1602 {
1603 int nAdjustWidth = 0;
1604 int nAdjustHeight = 0;
1605 SWP vSwpScroll;
1606
524d72c4
DW
1607 if (GetScrollBarHorz() == NULLHANDLE ||
1608 !WinIsWindowShowing(GetScrollBarHorz()))
1609 nAdjustHeight = 0L;
1610 else
859e65de 1611 nAdjustHeight = 20L;
524d72c4
DW
1612 if (GetScrollBarVert() == NULLHANDLE ||
1613 !WinIsWindowShowing(GetScrollBarVert()))
1614 nAdjustWidth = 0L;
1615 else
859e65de
DW
1616 nAdjustWidth = 20L;
1617 ::WinQueryWindowPos(GetHWND(), &vSwpScroll);
1618 ::WinSetWindowPos( GetHWND()
1619 ,HWND_TOP
1620 ,vSwpScroll.x
1621 ,vSwpScroll.y + nAdjustHeight
1622 ,vSwpScroll.cx - nAdjustWidth
1623 ,vSwpScroll.cy - nAdjustHeight
1624 ,SWP_MOVE | SWP_SIZE
1625 );
9175b262 1626 nYDiff -= nAdjustHeight;
859e65de
DW
1627 }
1628 MoveChildren(nYDiff);
1629 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1630 }
3bcf4cce
SN
1631#if 0
1632 // FIXME: By my logic, the next line should be needed as it moves child
1633 // windows when resizing the parent (see comment at beginning of
1634 // function). However, this seems to cause lots of problems. At
1635 // least, e.g. the grid sample almost works with this line
1636 // commented out but crashes badly with it.
9e705092 1637 MoveChildren(nHeightDelta);
3bcf4cce 1638#endif
0367c1c0 1639} // end of wxWindowOS2::DoMoveWindow
cdf1e714 1640
c86c44a0
DW
1641//
1642// Set the size of the window: if the dimensions are positive, just use them,
cdf1e714
DW
1643// but if any of them is equal to -1, it means that we must find the value for
1644// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1645// which case -1 is a valid value for x and y)
1646//
1647// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1648// the width/height to best suit our contents, otherwise we reuse the current
1649// width/height
c86c44a0 1650//
0367c1c0 1651void wxWindowOS2::DoSetSize(
a7ef993c
DW
1652 int nX
1653, int nY
1654, int nWidth
1655, int nHeight
1656, int nSizeFlags
1657)
cdf1e714 1658{
a7ef993c
DW
1659 //
1660 // Get the current size and position...
1661 //
1662 int nCurrentX;
1663 int nCurrentY;
1664 int nCurrentWidth;
1665 int nCurrentHeight;
542875a8 1666 wxSize vSize(-1, -1);
a7ef993c 1667
19193a2c
KB
1668 GetPosition(&nCurrentX, &nCurrentY);
1669 GetSize(&nCurrentWidth, &nCurrentHeight);
c86c44a0 1670
5d44b24e 1671 //
c86c44a0 1672 // ... and don't do anything (avoiding flicker) if it's already ok
5d44b24e
DW
1673 //
1674 //
1675 // Must convert Y coords to test for equality under OS/2
1676 //
1677 int nY2 = nY;
5d44b24e 1678
5d44b24e 1679 if (nX == nCurrentX && nY2 == nCurrentY &&
19193a2c 1680 nWidth == nCurrentWidth && nHeight == nCurrentHeight)
c86c44a0
DW
1681 {
1682 return;
1683 }
1684
a7ef993c
DW
1685 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1686 nX = nCurrentX;
542875a8 1687 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
a7ef993c 1688 nY = nCurrentY;
c86c44a0 1689
19193a2c 1690 AdjustForParentClientOrigin(nX, nY, nSizeFlags);
c86c44a0 1691
a7ef993c 1692 if (nWidth == -1)
c86c44a0 1693 {
a7ef993c 1694 if (nSizeFlags & wxSIZE_AUTO_WIDTH)
c86c44a0 1695 {
a7ef993c
DW
1696 vSize = DoGetBestSize();
1697 nWidth = vSize.x;
c86c44a0
DW
1698 }
1699 else
1700 {
a7ef993c
DW
1701 //
1702 // Just take the current one
1703 //
1704 nWidth = nCurrentWidth;
c86c44a0
DW
1705 }
1706 }
1707
a7ef993c 1708 if (nHeight == -1)
c86c44a0 1709 {
a7ef993c 1710 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
c86c44a0 1711 {
a7ef993c 1712 if (vSize.x == -1)
c86c44a0 1713 {
a7ef993c 1714 vSize = DoGetBestSize();
c86c44a0 1715 }
a7ef993c 1716 nHeight = vSize.y;
c86c44a0
DW
1717 }
1718 else
1719 {
1720 // just take the current one
a7ef993c 1721 nHeight = nCurrentHeight;
c86c44a0
DW
1722 }
1723 }
1724
a7ef993c
DW
1725 DoMoveWindow( nX
1726 ,nY
1727 ,nWidth
1728 ,nHeight
1729 );
0367c1c0 1730} // end of wxWindowOS2::DoSetSize
cdf1e714 1731
0367c1c0 1732void wxWindowOS2::DoSetClientSize(
a7ef993c
DW
1733 int nWidth
1734, int nHeight
1735)
cdf1e714 1736{
8330166c 1737 POINTL vPoint;
b720b24d
DW
1738 int nActualWidth;
1739 int nActualHeight;
1740 wxWindow* pParent = (wxWindow*)GetParent();
1741 HWND hParentWnd = (HWND)0;
c86c44a0 1742
b720b24d
DW
1743 if (pParent)
1744 hParentWnd = (HWND)pParent->GetHWND();
8330166c 1745
b720b24d
DW
1746 if (IsKindOf(CLASSINFO(wxFrame)))
1747 {
1748 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1749 HWND hFrame = pFrame->GetFrame();
1750 RECTL vRect;
1751 RECTL vRect2;
1752 RECTL vRect3;
c86c44a0 1753
b720b24d
DW
1754 ::WinQueryWindowRect(GetHwnd(), &vRect2);
1755 ::WinQueryWindowRect(hFrame, &vRect);
1756 ::WinQueryWindowRect(hParentWnd, &vRect3);
1757 nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
1758 nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
1759
1760 vPoint.x = vRect2.xLeft;
1761 vPoint.y = vRect2.yBottom;
1762 if (pParent)
1763 {
1764 vPoint.x -= vRect3.xLeft;
1765 vPoint.y -= vRect3.yBottom;
1766 }
1767 }
1768 else
8330166c 1769 {
b720b24d
DW
1770 int nX;
1771 int nY;
1772
1773 GetPosition(&nX, &nY);
1774 nActualWidth = nWidth;
1775 nActualHeight = nHeight;
1776
1777 vPoint.x = nX;
1778 vPoint.y = nY;
c86c44a0 1779 }
b720b24d
DW
1780 DoMoveWindow( vPoint.x
1781 ,vPoint.y
1782 ,nActualWidth
1783 ,nActualHeight
1784 );
19193a2c 1785
b720b24d
DW
1786 wxSizeEvent vEvent( wxSize( nWidth
1787 ,nHeight
1788 )
1789 ,m_windowId
1790 );
19193a2c 1791
a7ef993c
DW
1792 vEvent.SetEventObject(this);
1793 GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 1794} // end of wxWindowOS2::DoSetClientSize
cdf1e714 1795
cdf1e714
DW
1796// ---------------------------------------------------------------------------
1797// text metrics
1798// ---------------------------------------------------------------------------
1799
0367c1c0 1800int wxWindowOS2::GetCharHeight() const
cdf1e714 1801{
a7ef993c
DW
1802 HPS hPs;
1803 FONTMETRICS vFontMetrics;
cdf1e714 1804
a7ef993c
DW
1805 hPs = ::WinGetPS(GetHwnd());
1806
542875a8 1807 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1808 {
1809 ::WinReleasePS(hPs);
a7ef993c 1810 return (0);
b7084589 1811 }
a7ef993c 1812 ::WinReleasePS(hPs);
b7084589 1813 return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender);
0367c1c0 1814} // end of wxWindowOS2::GetCharHeight
a7ef993c 1815
0367c1c0 1816int wxWindowOS2::GetCharWidth() const
cdf1e714 1817{
542875a8
DW
1818 HPS hPs;
1819 FONTMETRICS vFontMetrics;
1820
a7ef993c 1821 hPs = ::WinGetPS(GetHwnd());
cdf1e714 1822
542875a8 1823 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1824 {
1825 ::WinReleasePS(hPs);
a7ef993c 1826 return (0);
b7084589 1827 }
a7ef993c 1828 ::WinReleasePS(hPs);
b7084589 1829 return(vFontMetrics.lAveCharWidth);
0367c1c0 1830} // end of wxWindowOS2::GetCharWidth
a7ef993c 1831
0367c1c0 1832void wxWindowOS2::GetTextExtent(
a7ef993c
DW
1833 const wxString& rString
1834, int* pX
1835, int* pY
1836, int* pDescent
1837, int* pExternalLeading
1838, const wxFont* pTheFont
1839) const
cdf1e714 1840{
987da0d4
DW
1841 POINTL avPoint[TXTBOX_COUNT];
1842 POINTL vPtMin;
1843 POINTL vPtMax;
1844 int i;
1845 int l;
1846 FONTMETRICS vFM; // metrics structure
72bfca58 1847 BOOL bRc = FALSE;
987da0d4 1848 char* pStr;
987da0d4 1849 HPS hPS;
19193a2c 1850
a7ef993c 1851
987da0d4 1852 hPS = ::WinGetPS(GetHwnd());
a7ef993c 1853
987da0d4
DW
1854 l = rString.Length();
1855 if (l > 0L)
1856 {
1857 pStr = (PCH)rString.c_str();
a7ef993c 1858
987da0d4
DW
1859 //
1860 // In world coordinates.
1861 //
1862 bRc = ::GpiQueryTextBox( hPS
1863 ,l
1864 ,pStr
1865 ,TXTBOX_COUNT // return maximum information
1866 ,avPoint // array of coordinates points
1867 );
1868 if (bRc)
1869 {
1870 vPtMin.x = avPoint[0].x;
1871 vPtMax.x = avPoint[0].x;
1872 vPtMin.y = avPoint[0].y;
1873 vPtMax.y = avPoint[0].y;
1874 for (i = 1; i < 4; i++)
1875 {
1876 if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
1877 if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
1878 if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
1879 if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
1880 }
1881 bRc = ::GpiQueryFontMetrics( hPS
1882 ,sizeof(FONTMETRICS)
1883 ,&vFM
1884 );
1885 if (!bRc)
1886 {
1887 vPtMin.x = 0;
1888 vPtMin.y = 0;
1889 vPtMax.x = 0;
1890 vPtMax.y = 0;
1891 }
1892 }
1893 else
1894 {
1895 vPtMin.x = 0;
1896 vPtMin.y = 0;
1897 vPtMax.x = 0;
1898 vPtMax.y = 0;
1899 }
1900 }
1901 else
a7ef993c 1902 {
987da0d4
DW
1903 vPtMin.x = 0;
1904 vPtMin.y = 0;
1905 vPtMax.x = 0;
1906 vPtMax.y = 0;
a7ef993c 1907 }
987da0d4
DW
1908 if (pX)
1909 *pX = (vPtMax.x - vPtMin.x + 1);
1910 if (pY)
1911 *pY = (vPtMax.y - vPtMin.y + 1);
1912 if (pDescent)
1913 {
1914 if (bRc)
1915 *pDescent = vFM.lMaxDescender;
1916 else
1917 *pDescent = 0;
1918 }
1919 if (pExternalLeading)
1920 {
1921 if (bRc)
1922 *pExternalLeading = vFM.lExternalLeading;
1923 else
1924 *pExternalLeading = 0;
1925 }
1926 ::WinReleasePS(hPS);
1927} // end of wxWindow::GetTextExtent
cdf1e714 1928
f9efbe3a
DW
1929bool wxWindowOS2::IsMouseInWindow() const
1930{
1931 //
1932 // Get the mouse position
1933 POINTL vPt;
1934
1935 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
1936
1937 //
1938 // Find the window which currently has the cursor and go up the window
1939 // chain until we find this window - or exhaust it
1940 //
1941 HWND hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPt, TRUE);
1942
1943 while (hWnd && (hWnd != GetHwnd()))
1944 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
1945
1946 return hWnd != NULL;
1947} // end of wxWindowOS2::IsMouseInWindow
1948
cdf1e714
DW
1949
1950// ---------------------------------------------------------------------------
1951// popup menu
1952// ---------------------------------------------------------------------------
19193a2c 1953//
19193a2c 1954#if wxUSE_MENUS_NATIVE
0367c1c0 1955bool wxWindowOS2::DoPopupMenu(
61243a51
DW
1956 wxMenu* pMenu
1957, int nX
1958, int nY
1959)
cdf1e714 1960{
239c2e96
DW
1961 HWND hWndOwner = GetHwnd();
1962 HWND hWndParent = GetHwnd();
61243a51 1963 HWND hMenu = GetHmenuOf(pMenu);
239c2e96 1964 bool bIsWaiting = TRUE;
c82be69b
JS
1965 int nHeight;
1966
1967 // Protect against recursion
1968 if (wxCurrentPopupMenu)
1969 return false;
61243a51
DW
1970
1971 pMenu->SetInvokingWindow(this);
1972 pMenu->UpdateUI();
c82be69b 1973
5d826f60 1974 if ( nX == -1 && nY == -1 )
971562cb
VS
1975 {
1976 wxPoint mouse = wxGetMousePosition();
1977 nX = mouse.x; nY = mouse.y;
1978 }
1979 else
1980 {
1981 DoClientToScreen( &nX
1982 ,&nY
1983 );
c82be69b
JS
1984 DoGetSize(0,&nHeight);
1985 nY = nHeight - nY;
971562cb 1986 }
61243a51
DW
1987 wxCurrentPopupMenu = pMenu;
1988
1989 ::WinPopupMenu( hWndParent
239c2e96 1990 ,hWndOwner
61243a51
DW
1991 ,hMenu
1992 ,nX
1993 ,nY
1994 ,0L
bdfd8d77 1995 ,PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 | PU_KEYBOARD
61243a51 1996 );
bdfd8d77 1997
239c2e96
DW
1998 while(bIsWaiting)
1999 {
bdfd8d77 2000 QMSG vMsg;
239c2e96 2001
c82be69b
JS
2002 ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
2003 if (vMsg.msg == WM_COMMAND)
bdfd8d77 2004 bIsWaiting = FALSE;
bdfd8d77 2005 ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
239c2e96 2006 }
c82be69b 2007
61243a51 2008 wxCurrentPopupMenu = NULL;
61243a51
DW
2009 pMenu->SetInvokingWindow(NULL);
2010 return TRUE;
0367c1c0 2011} // end of wxWindowOS2::DoPopupMenu
19193a2c 2012#endif // wxUSE_MENUS_NATIVE
cdf1e714
DW
2013
2014// ===========================================================================
2015// pre/post message processing
2016// ===========================================================================
2017
0367c1c0 2018MRESULT wxWindowOS2::OS2DefWindowProc(
61243a51
DW
2019 WXUINT uMsg
2020, WXWPARAM wParam
2021, WXLPARAM lParam
2022)
cdf1e714 2023{
61243a51 2024 if (m_fnOldWndProc)
19193a2c 2025 return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
61243a51 2026 else
19193a2c 2027 return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
0367c1c0 2028} // end of wxWindowOS2::OS2DefWindowProc
cdf1e714 2029
0367c1c0 2030bool wxWindowOS2::OS2ProcessMessage(
61243a51
DW
2031 WXMSG* pMsg
2032)
cdf1e714 2033{
19193a2c
KB
2034// wxUniversal implements tab traversal itself
2035#ifndef __WXUNIVERSAL__
61243a51
DW
2036 QMSG* pQMsg = (QMSG*)pMsg;
2037
2038 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
2039 {
2040 //
2041 // Intercept dialog navigation keys
2042 //
2043 bool bProcess = TRUE;
2044 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
2045
2046 if (uKeyFlags & KC_KEYUP)
2047 bProcess = FALSE;
2048
2049 if (uKeyFlags & KC_ALT)
2050 bProcess = FALSE;
2051
2052 if (!(uKeyFlags & KC_VIRTUALKEY))
2053 bProcess = FALSE;
2054
2055 if (bProcess)
2056 {
2057 bool bCtrlDown = IsCtrlDown();
2058 bool bShiftDown = IsShiftDown();
2059
2060 //
2061 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
2062 // don't process it if it's the case (except for Ctrl-Tab/Enter
2063 // combinations which are always processed)
2064 //
2065 ULONG ulDlgCode = 0;
2066
2067 if (!bCtrlDown)
2068 {
2069 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
2070 }
2071
2072 bool bForward = TRUE;
2073 bool bWindowChange = FALSE;
2074
2075 switch (SHORT2FROMMP(pQMsg->mp2))
2076 {
2077 //
2078 // Going to make certain assumptions about specific types of controls
2079 // here, so we may have to alter some things later if they prove invalid
2080 //
2081 case VK_TAB:
2082 //
2083 // Shift tabl will always be a nav-key but tabs may be wanted
2084 //
2085 if (!bShiftDown)
2086 {
2087 bProcess = FALSE;
2088 }
2089 else
2090 {
2091 //
2092 // Entry Fields want tabs for themselve usually
2093 //
2094 switch (ulDlgCode)
2095 {
2096 case DLGC_ENTRYFIELD:
2097 case DLGC_MLE:
2098 bProcess = TRUE;
2099 break;
2100
2101 default:
2102 bProcess = FALSE;
2103 }
2104
2105 //
2106 // Ctrl-Tab cycles thru notebook pages
2107 //
2108 bWindowChange = bCtrlDown;
2109 bForward = !bShiftDown;
2110 }
2111 break;
2112
2113 case VK_UP:
2114 case VK_LEFT:
2115 if (bCtrlDown)
2116 bProcess = FALSE;
2117 else
2118 bForward = FALSE;
2119 break;
2120
2121 case VK_DOWN:
2122 case VK_RIGHT:
2123 if (bCtrlDown)
2124 bProcess = FALSE;
2125 break;
2126
2127 case VK_ENTER:
2128 {
2129 if (bCtrlDown)
2130 {
2131 //
2132 // ctrl-enter is not processed
2133 //
2134 return FALSE;
2135 }
2136 else if (ulDlgCode & DLGC_BUTTON)
2137 {
2138 //
2139 // buttons want process Enter themselevs
2140 //
2141 bProcess = FALSE;
2142 }
2143 else
2144 {
1bcfc0e1
DW
2145 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
2146 ,wxButton
2147 );
61243a51
DW
2148
2149 if (pBtn && pBtn->IsEnabled())
2150 {
2151 //
2152 // If we do have a default button, do press it
2153 //
2154 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
2155 return TRUE;
2156 }
2b5f62a0
VZ
2157 else if (!IsTopLevel())
2158 {
2159 //
2160 // if not a top level window, let parent
2161 // handle it
2162 //
2163 return FALSE;
2164 }
61243a51
DW
2165 // else: but if it does not it makes sense to make
2166 // it work like a TAB - and that's what we do.
2167 // Note that Ctrl-Enter always works this way.
2168 }
2169 }
2170 break;
2171
2172 default:
2173 bProcess = FALSE;
2174 }
2175
2176 if (bProcess)
2177 {
2178 wxNavigationKeyEvent vEvent;
2179
2180 vEvent.SetDirection(bForward);
2181 vEvent.SetWindowChange(bWindowChange);
2182 vEvent.SetEventObject(this);
2183
2184 if (GetEventHandler()->ProcessEvent(vEvent))
2185 {
2186 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2187
2188 if (pBtn)
2189 {
2190 //
2191 // The button which has focus should be default
2192 //
2193 pBtn->SetDefault();
2194 }
2195 return TRUE;
2196 }
2197 }
2198 }
dae16775
DW
2199 //
2200 // Let Dialogs process
2201 //
2202 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
2203 return TRUE;
61243a51 2204 }
19193a2c
KB
2205#else
2206 pMsg = pMsg; // just shut up the compiler
2207#endif // __WXUNIVERSAL__
61243a51 2208
cdf1e714 2209 return FALSE;
0367c1c0 2210} // end of wxWindowOS2::OS2ProcessMessage
cdf1e714 2211
0367c1c0 2212bool wxWindowOS2::OS2TranslateMessage(
61243a51
DW
2213 WXMSG* pMsg
2214)
cdf1e714 2215{
19193a2c 2216#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
7e99520b
DW
2217 return m_acceleratorTable.Translate(m_hWnd, pMsg);
2218#else
19193a2c 2219 pMsg = pMsg;
7e99520b
DW
2220 return FALSE;
2221#endif //wxUSE_ACCEL
0367c1c0 2222} // end of wxWindowOS2::OS2TranslateMessage
cdf1e714 2223
54ffa107
DW
2224bool wxWindowOS2::OS2ShouldPreProcessMessage(
2225 WXMSG* pMsg
2226)
2227{
2228 // preprocess all messages by default
2229 return TRUE;
2230} // end of wxWindowOS2::OS2ShouldPreProcessMessage
2231
cdf1e714 2232// ---------------------------------------------------------------------------
61243a51 2233// message params unpackers
cdf1e714
DW
2234// ---------------------------------------------------------------------------
2235
0367c1c0 2236void wxWindowOS2::UnpackCommand(
61243a51
DW
2237 WXWPARAM wParam
2238, WXLPARAM lParam
2239, WORD* pId
2240, WXHWND* phWnd
2241, WORD* pCmd
2242)
cdf1e714 2243{
5b3ed311
DW
2244 *pId = LOWORD(wParam);
2245 *phWnd = NULL; // or may be GetHWND() ?
2246 *pCmd = LOWORD(lParam);
0367c1c0 2247} // end of wxWindowOS2::UnpackCommand
cdf1e714 2248
0367c1c0 2249void wxWindowOS2::UnpackActivate(
61243a51
DW
2250 WXWPARAM wParam
2251, WXLPARAM lParam
2252, WXWORD* pState
2253, WXHWND* phWnd
2254)
cdf1e714 2255{
61243a51
DW
2256 *pState = LOWORD(wParam);
2257 *phWnd = (WXHWND)lParam;
0367c1c0 2258} // end of wxWindowOS2::UnpackActivate
cdf1e714 2259
0367c1c0 2260void wxWindowOS2::UnpackScroll(
61243a51
DW
2261 WXWPARAM wParam
2262, WXLPARAM lParam
2263, WXWORD* pCode
2264, WXWORD* pPos
2265, WXHWND* phWnd
2266)
cdf1e714 2267{
b7d8f285
DW
2268 ULONG ulId;
2269 HWND hWnd;
2270
2271 ulId = (ULONG)LONGFROMMP(wParam);
2272 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2273 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2274 *phWnd = NULLHANDLE;
2275 else
2276 *phWnd = hWnd;
2277
2278 *pPos = SHORT1FROMMP(lParam);
2279 *pCode = SHORT2FROMMP(lParam);
0367c1c0 2280} // end of wxWindowOS2::UnpackScroll
61243a51 2281
0367c1c0 2282void wxWindowOS2::UnpackMenuSelect(
61243a51
DW
2283 WXWPARAM wParam
2284, WXLPARAM lParam
2285, WXWORD* pItem
2286, WXWORD* pFlags
2287, WXHMENU* phMenu
2288)
cdf1e714 2289{
61243a51
DW
2290 *pItem = (WXWORD)LOWORD(wParam);
2291 *pFlags = HIWORD(wParam);
2292 *phMenu = (WXHMENU)lParam;
0367c1c0 2293} // end of wxWindowOS2::UnpackMenuSelect
cdf1e714
DW
2294
2295// ---------------------------------------------------------------------------
77ffb593 2296// Main wxWidgets window proc and the window proc for wxWindow
cdf1e714
DW
2297// ---------------------------------------------------------------------------
2298
61243a51 2299//
cdf1e714
DW
2300// Hook for new window just as it's being created, when the window isn't yet
2301// associated with the handle
61243a51 2302//
19193a2c 2303wxWindowOS2* wxWndHook = NULL;
cdf1e714 2304
61243a51 2305//
cdf1e714 2306// Main window proc
61243a51 2307//
f23208ca 2308MRESULT EXPENTRY wxWndProc(
61243a51
DW
2309 HWND hWnd
2310, ULONG ulMsg
2311, MPARAM wParam
2312, MPARAM lParam
2313)
cdf1e714 2314{
19193a2c 2315 wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
cdf1e714 2316
61243a51
DW
2317 //
2318 // When we get the first message for the HWND we just created, we associate
cdf1e714 2319 // it with wxWindow stored in wxWndHook
61243a51
DW
2320 //
2321 if (!pWnd && wxWndHook)
cdf1e714 2322 {
cdf1e714 2323 wxAssociateWinWithHandle(hWnd, wxWndHook);
61243a51 2324 pWnd = wxWndHook;
cdf1e714 2325 wxWndHook = NULL;
61243a51 2326 pWnd->SetHWND((WXHWND)hWnd);
cdf1e714
DW
2327 }
2328
5b3ed311 2329 MRESULT rc = (MRESULT)0;
e604d44b 2330
cdf1e714 2331
61243a51 2332 //
cdf1e714 2333 // Stop right here if we don't have a valid handle in our wxWindow object.
61243a51
DW
2334 //
2335 if (pWnd && !pWnd->GetHWND())
cdf1e714 2336 {
61243a51
DW
2337 pWnd->SetHWND((WXHWND) hWnd);
2338 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2339 pWnd->SetHWND(0);
cdf1e714
DW
2340 }
2341 else
2342 {
61243a51 2343 if (pWnd)
45e0dc94 2344 {
61243a51 2345 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
45e0dc94
DW
2346 if ( (pWnd->GetScrollBarHorz() != NULLHANDLE ||
2347 pWnd->GetScrollBarVert() != NULLHANDLE) &&
2348 ulMsg == WM_PAINT)
2349 {
2350 if (pWnd->GetScrollBarHorz() != NULLHANDLE)
2351 ::WinInvalidateRect(pWnd->GetScrollBarHorz(), NULL, TRUE);
2352 if (pWnd->GetScrollBarVert() != NULLHANDLE)
2353 ::WinInvalidateRect(pWnd->GetScrollBarVert(), NULL, TRUE);
2354 }
2355 }
e604d44b 2356 else
61243a51 2357 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
cdf1e714 2358 }
5b3ed311 2359
cdf1e714 2360 return rc;
61243a51 2361} // end of wxWndProc
cdf1e714 2362
61243a51
DW
2363//
2364// We will add (or delete) messages we need to handle at this default
2365// level as we go
2366//
0367c1c0 2367MRESULT wxWindowOS2::OS2WindowProc(
61243a51
DW
2368 WXUINT uMsg
2369, WXWPARAM wParam
2370, WXLPARAM lParam
2371)
cdf1e714 2372{
61243a51
DW
2373 //
2374 // Did we process the uMsg?
2375 //
2376 bool bProcessed = FALSE;
e604d44b 2377 MRESULT mResult;
cdf1e714 2378
61243a51
DW
2379 //
2380 // For most messages we should return 0 when we do process the message
2381 //
e604d44b 2382 mResult = (MRESULT)0;
61243a51
DW
2383
2384 switch (uMsg)
cdf1e714
DW
2385 {
2386 case WM_CREATE:
2387 {
61243a51
DW
2388 bool bMayCreate;
2389
2390 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2391 ,&bMayCreate
2392 );
2393 if (bProcessed)
cdf1e714 2394 {
61243a51
DW
2395 //
2396 // Return 0 to bAllow window creation
2397 //
e604d44b 2398 mResult = (MRESULT)(bMayCreate ? 0 : -1);
cdf1e714
DW
2399 }
2400 }
2401 break;
2402
2403 case WM_DESTROY:
e604d44b
DW
2404 HandleDestroy();
2405 bProcessed = TRUE;
e604d44b 2406 break;
cdf1e714
DW
2407
2408 case WM_MOVE:
61243a51
DW
2409 bProcessed = HandleMove( LOWORD(lParam)
2410 ,HIWORD(lParam)
2411 );
cdf1e714
DW
2412 break;
2413
2414 case WM_SIZE:
61243a51
DW
2415 bProcessed = HandleSize( LOWORD(lParam)
2416 ,HIWORD(lParam)
2417 ,(WXUINT)wParam
2418 );
cdf1e714
DW
2419 break;
2420
e37db699
DW
2421 case WM_WINDOWPOSCHANGED:
2422
2423 //
2424 // Dialogs under OS/2 do not get WM_SIZE events at all.
2425 // Instead they get this, which can function much like WM_SIZE
2426 // PSWP contains the new sizes and positioning, PSWP+1 the old
2427 // We use this because ADJUSTWINDOWPOS comes BEFORE the new
2428 // position is added and our auto layout does a WinQueryWindowRect
2429 // to get the CURRENT client size. That is the size used to position
2430 // child controls, so we need to already be sized
2431 // in order to get the child controls positoned properly.
2432 //
626af800 2433 if (IsKindOf(CLASSINFO(wxDialog)) || IsKindOf(CLASSINFO(wxFrame)))
e37db699
DW
2434 {
2435 PSWP pSwp = (PSWP)PVOIDFROMMP(wParam);
f3e4a2a4
DW
2436 PSWP pSwp2 = pSwp++;
2437
2438 if (!(pSwp->cx == pSwp2->cx &&
2439 pSwp->cy == pSwp2->cy))
2440 bProcessed = HandleSize( pSwp->cx
2441 ,pSwp->cy
2442 ,(WXUINT)lParam
2443 );
626af800
DW
2444 if (IsKindOf(CLASSINFO(wxFrame)))
2445 {
2446 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
2447
2448 if (pFrame)
2449 {
2450 if (pFrame->GetStatusBar())
2451 pFrame->PositionStatusBar();
2590f154
DW
2452 if (pFrame->GetToolBar())
2453 pFrame->PositionToolBar();
626af800
DW
2454 }
2455 }
e37db699
DW
2456 }
2457 break;
2458
cdf1e714
DW
2459 case WM_ACTIVATE:
2460 {
61243a51
DW
2461 WXWORD wState;
2462 WXHWND hWnd;
2463
2464 UnpackActivate( wParam
2465 ,lParam
2466 ,&wState
2467 ,&hWnd
2468 );
2469
2470 bProcessed = HandleActivate( wState
2471 ,(WXHWND)hWnd
2472 );
e604d44b 2473 bProcessed = FALSE;
cdf1e714
DW
2474 }
2475 break;
2476
2477 case WM_SETFOCUS:
61243a51
DW
2478 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2479 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2480 else
2481 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
cdf1e714
DW
2482 break;
2483
2484 case WM_PAINT:
61243a51 2485 bProcessed = HandlePaint();
cdf1e714
DW
2486 break;
2487
2488 case WM_CLOSE:
61243a51
DW
2489 //
2490 // Don't let the DefWindowProc() destroy our window - we'll do it
cdf1e714 2491 // ourselves in ~wxWindow
61243a51
DW
2492 //
2493 bProcessed = TRUE;
e604d44b 2494 mResult = (MRESULT)TRUE;
cdf1e714
DW
2495 break;
2496
61243a51
DW
2497 case WM_SHOW:
2498 bProcessed = HandleShow(wParam != 0, (int)lParam);
cdf1e714
DW
2499 break;
2500
61243a51
DW
2501 //
2502 // Under OS2 PM Joysticks are treated just like mouse events
2503 // The "Motion" events will be prevelent in joysticks
2504 //
cdf1e714 2505 case WM_MOUSEMOVE:
61243a51
DW
2506 case WM_BUTTON1DOWN:
2507 case WM_BUTTON1UP:
2508 case WM_BUTTON1DBLCLK:
2509 case WM_BUTTON1MOTIONEND:
2510 case WM_BUTTON1MOTIONSTART:
2511 case WM_BUTTON2DOWN:
2512 case WM_BUTTON2UP:
2513 case WM_BUTTON2DBLCLK:
2514 case WM_BUTTON2MOTIONEND:
2515 case WM_BUTTON2MOTIONSTART:
2516 case WM_BUTTON3DOWN:
2517 case WM_BUTTON3UP:
2518 case WM_BUTTON3DBLCLK:
2519 case WM_BUTTON3MOTIONEND:
2520 case WM_BUTTON3MOTIONSTART:
cdf1e714 2521 {
430974f8
DW
2522 if (uMsg == WM_BUTTON1DOWN && AcceptsFocus())
2523 SetFocus();
2524
2525 short nX = LOWORD(wParam);
2526 short nY = HIWORD(wParam);
cdf1e714 2527
430974f8
DW
2528 //
2529 // Redirect the event to a static control if necessary
2530 //
2531 if (this == GetCapture())
2532 {
2533 bProcessed = HandleMouseEvent( uMsg
2534 ,nX
2535 ,nY
8d902dd6 2536 ,(WXUINT)SHORT2FROMMP(lParam)
430974f8
DW
2537 );
2538 }
2539 else
2540 {
2541 wxWindow* pWin = FindWindowForMouseEvent( this
2542 ,&nX
2543 ,&nY
2544 );
376ef4a1
DW
2545 if (!pWin->IsOfStandardClass())
2546 {
2547 if (uMsg == WM_BUTTON1DOWN && pWin->AcceptsFocus() )
2548 pWin->SetFocus();
2549 }
430974f8
DW
2550 bProcessed = pWin->HandleMouseEvent( uMsg
2551 ,nX
2552 ,nY
8d902dd6 2553 ,(WXUINT)SHORT2FROMMP(lParam)
430974f8
DW
2554 );
2555 }
cdf1e714
DW
2556 }
2557 break;
430974f8 2558
cdf1e714 2559 case WM_SYSCOMMAND:
61243a51 2560 bProcessed = HandleSysCommand(wParam, lParam);
cdf1e714
DW
2561 break;
2562
2563 case WM_COMMAND:
2564 {
2565 WORD id, cmd;
2566 WXHWND hwnd;
2567 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2568
61243a51 2569 bProcessed = HandleCommand(id, cmd, hwnd);
cdf1e714
DW
2570 }
2571 break;
2572
61243a51
DW
2573 //
2574 // For these messages we must return TRUE if process the message
2575 //
cdf1e714
DW
2576 case WM_DRAWITEM:
2577 case WM_MEASUREITEM:
2578 {
45bedfdd 2579 int nIdCtrl = (UINT)wParam;
45bedfdd 2580
61243a51 2581 if ( uMsg == WM_DRAWITEM )
cdf1e714 2582 {
45bedfdd 2583 bProcessed = OS2OnDrawItem(nIdCtrl,
cdf1e714
DW
2584 (WXDRAWITEMSTRUCT *)lParam);
2585 }
2586 else
2587 {
f5ea767e
DW
2588 return MRFROMLONG(OS2OnMeasureItem( nIdCtrl
2589 ,(WXMEASUREITEMSTRUCT *)lParam
2590 ));
cdf1e714
DW
2591 }
2592
61243a51 2593 if ( bProcessed )
e604d44b 2594 mResult = (MRESULT)TRUE;
cdf1e714
DW
2595 }
2596 break;
2597
61243a51 2598 case WM_QUERYDLGCODE:
47df2b8c 2599 if (!IsOfStandardClass())
cdf1e714 2600 {
47df2b8c
DW
2601 if ( m_lDlgCode )
2602 {
2603 mResult = (MRESULT)m_lDlgCode;
2604 bProcessed = TRUE;
2605 }
cdf1e714 2606 }
61243a51 2607 //
cdf1e714 2608 //else: get the dlg code from the DefWindowProc()
61243a51 2609 //
cdf1e714
DW
2610 break;
2611
61243a51
DW
2612 //
2613 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2614 // and key-down events are obtained from the WM_CHAR params.
2615 //
2616 case WM_CHAR:
cdf1e714 2617 {
61243a51 2618 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 2619
61243a51
DW
2620 if (uKeyFlags & KC_KEYUP)
2621 {
19193a2c 2622 //TODO: check if the cast to WXWORD isn't causing trouble
a086de98 2623 bProcessed = HandleKeyUp(wParam, lParam);
cdf1e714 2624 break;
61243a51
DW
2625 }
2626 else // keydown event
2627 {
3437f881 2628 m_bLastKeydownProcessed = FALSE;
61243a51
DW
2629 //
2630 // If this has been processed by an event handler,
2631 // return 0 now (we've handled it). DON't RETURN
2632 // we still need to process further
2633 //
a086de98 2634 m_bLastKeydownProcessed = HandleKeyDown(wParam, lParam);
61243a51 2635 if (uKeyFlags & KC_VIRTUALKEY)
cdf1e714 2636 {
61243a51
DW
2637 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2638
2639 //
2640 // We consider these message "not interesting" to OnChar
2641 //
61243a51
DW
2642 switch(uVk)
2643 {
a086de98
DW
2644 case VK_SHIFT:
2645 case VK_CTRL:
2646 case VK_MENU:
2647 case VK_CAPSLOCK:
2648 case VK_NUMLOCK:
2649 case VK_SCRLLOCK:
2650 bProcessed = TRUE;
2651 break;
2652
61243a51
DW
2653 // Avoid duplicate messages to OnChar for these ASCII keys: they
2654 // will be translated by TranslateMessage() and received in WM_CHAR
2655 case VK_ESC:
61243a51
DW
2656 case VK_ENTER:
2657 case VK_BACKSPACE:
2658 case VK_TAB:
2659 // But set processed to FALSE, not TRUE to still pass them to
2660 // the control's default window proc - otherwise built-in
2661 // keyboard handling won't work
2662 bProcessed = FALSE;
2663 break;
2664
61243a51 2665 default:
598d8cac 2666 bProcessed = HandleChar(wParam, lParam);
61243a51
DW
2667 }
2668 break;
cdf1e714 2669 }
61243a51
DW
2670 else // WM_CHAR -- Always an ASCII character
2671 {
a086de98
DW
2672 if (m_bLastKeydownProcessed)
2673 {
2674 //
2675 // The key was handled in the EVT_KEY_DOWN and handling
2676 // a key in an EVT_KEY_DOWN handler is meant, by
2677 // design, to prevent EVT_CHARs from happening
2678 //
2679 m_bLastKeydownProcessed = FALSE;
2680 bProcessed = TRUE;
2681 }
2682 else // do generate a CHAR event
2683 {
598d8cac 2684 bProcessed = HandleChar(wParam, lParam, TRUE);
a086de98
DW
2685 break;
2686 }
61243a51
DW
2687 }
2688 }
cdf1e714 2689 }
cdf1e714
DW
2690
2691 case WM_HSCROLL:
2692 case WM_VSCROLL:
2693 {
61243a51
DW
2694 WXWORD wCode;
2695 WXWORD wPos;
2696 WXHWND hWnd;
2697 UnpackScroll( wParam
2698 ,lParam
2699 ,&wCode
2700 ,&wPos
2701 ,&hWnd
2702 );
2703
2704 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2705 : wxVERTICAL
2706 ,wCode
2707 ,wPos
2708 ,hWnd
2709 );
cdf1e714
DW
2710 }
2711 break;
2712
3c299c3a
DW
2713 case WM_CONTROL:
2714 switch(SHORT2FROMMP(wParam))
2715 {
a5799260
DW
2716 case BN_PAINT:
2717 {
2718 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2719 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2720
2721 if (!pWin)
2722 {
2723 bProcessed = FALSE;
2724 break;
2725 }
2726 if (pWin->IsKindOf(CLASSINFO(wxBitmapButton)))
2727 {
2728 wxBitmapButton* pBitmapButton = wxDynamicCast(pWin, wxBitmapButton);
2729
2730 pBitmapButton->OS2OnDraw((WXDRAWITEMSTRUCT *)lParam);
2731 }
2732 return 0;
2733 }
2734 break;
2735
1de4baa3
DW
2736 case BKN_PAGESELECTEDPENDING:
2737 {
2738 PPAGESELECTNOTIFY pPage = (PPAGESELECTNOTIFY)lParam;
2739
2740 if ((pPage->ulPageIdNew != pPage->ulPageIdCur) &&
2741 (pPage->ulPageIdNew > 0L && pPage->ulPageIdCur > 0L))
2742 {
2743 wxWindowOS2* pWin = wxFindWinFromHandle(pPage->hwndBook);
2744 wxNotebookEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
2745 ,(int)SHORT1FROMMP(wParam)
2746 ,(int)pPage->ulPageIdNew
2747 ,(int)pPage->ulPageIdCur
2748 );
2749 if (!pWin)
2750 {
2751 bProcessed = FALSE;
2752 break;
2753 }
2754 if (pWin->IsKindOf(CLASSINFO(wxNotebook)))
2755 {
2756 wxNotebook* pNotebook = wxDynamicCast(pWin, wxNotebook);
2757
2758 vEvent.SetEventObject(pWin);
2759 pNotebook->OnSelChange(vEvent);
2760 bProcessed = TRUE;
2761 }
2762 else
2763 bProcessed = FALSE;
2764 }
2765 else
2766 bProcessed = FALSE;
2767 }
2768 break;
2769
2770 case BN_CLICKED: // Dups as LN_SELECT and CBN_LBSELECT
f289196b
DW
2771 {
2772 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2773 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2774
2775 if (!pWin)
2776 {
2777 bProcessed = FALSE;
2778 break;
2779 }
2780 //
77ffb593 2781 // Simulate a WM_COMMAND here, as wxWidgets expects all control
f289196b
DW
2782 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2783 //
2784 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
2785 {
2786 wxRadioBox* pRadioBox = wxDynamicCast(pWin, wxRadioBox);
2787
2788 pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2789 ,(WXUINT)SHORT1FROMMP(wParam)
2790 );
2791 }
2792 if (pWin->IsKindOf(CLASSINFO(wxRadioButton)))
2793 {
2794 wxRadioButton* pRadioButton = wxDynamicCast(pWin, wxRadioButton);
2795
2796 pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2797 ,(WXUINT)SHORT1FROMMP(wParam)
2798 );
2799 }
2800 if (pWin->IsKindOf(CLASSINFO(wxCheckBox)))
2801 {
2802 wxCheckBox* pCheckBox = wxDynamicCast(pWin, wxCheckBox);
2803
2804 pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2805 ,(WXUINT)SHORT1FROMMP(wParam)
2806 );
2807 }
1de4baa3
DW
2808 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2809 {
2810 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2811
2812 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2813 ,(WXUINT)SHORT1FROMMP(wParam)
2814 );
2815 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2816 Refresh();
2817 }
2818 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2819 {
2820 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2821
2822 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2823 ,(WXUINT)SHORT1FROMMP(wParam)
2824 );
2825 }
2826 return 0;
2827 }
2828 break;
2829
2830 case LN_ENTER: /* dups as CBN_EFCHANGE */
2831 {
2832 HWND hWnd = HWNDFROMMP(lParam);
2833 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2834
2835 if (!pWin)
2836 {
2837 bProcessed = FALSE;
2838 break;
2839 }
2840 //
77ffb593 2841 // Simulate a WM_COMMAND here, as wxWidgets expects all control
1de4baa3
DW
2842 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2843 //
2844 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2845 {
2846 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2847
2848 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2849 ,(WXUINT)SHORT1FROMMP(wParam)
2850 );
2851 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2852 Refresh();
2853
2854 }
2855 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2856 {
2857 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2858
2859 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2860 ,(WXUINT)SHORT1FROMMP(wParam)
2861 );
2862 }
f289196b
DW
2863 return 0;
2864 }
2865 break;
2866
3c299c3a
DW
2867 case SPBN_UPARROW:
2868 case SPBN_DOWNARROW:
2869 case SPBN_CHANGE:
2870 {
2871 char zVal[10];
2872 long lVal;
2873
2874 ::WinSendMsg( HWNDFROMMP(lParam)
2875 ,SPBM_QUERYVALUE
2876 ,&zVal
2877 ,MPFROM2SHORT( (USHORT)10
2878 ,(USHORT)SPBQ_UPDATEIFVALID
2879 )
2880 );
2881 lVal = atol(zVal);
2882 bProcessed = OS2OnScroll( wxVERTICAL
2883 ,(int)SHORT2FROMMP(wParam)
2884 ,(int)lVal
2885 ,HWNDFROMMP(lParam)
2886 );
2887 }
2888 break;
2889
2890 case SLN_SLIDERTRACK:
2891 {
2892 HWND hWnd = ::WinWindowFromID(GetHWND(), SHORT1FROMMP(wParam));
2893 wxWindowOS2* pChild = wxFindWinFromHandle(hWnd);
2894
b389a12d
DW
2895 if (!pChild)
2896 {
2897 bProcessed = FALSE;
2898 break;
2899 }
3c299c3a
DW
2900 if (pChild->IsKindOf(CLASSINFO(wxSlider)))
2901 bProcessed = OS2OnScroll( wxVERTICAL
2902 ,(int)SHORT2FROMMP(wParam)
2903 ,(int)LONGFROMMP(lParam)
2904 ,hWnd
2905 );
2906 }
2907 break;
2908 }
2909 break;
2910
61243a51
DW
2911#if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2912 case WM_CTLCOLORCHANGE:
cdf1e714 2913 {
e604d44b 2914 bProcessed = HandleCtlColor(&hBrush);
61243a51
DW
2915 }
2916 break;
2917#endif
8d854fa9
DW
2918 case WM_ERASEBACKGROUND:
2919 //
2920 // Returning TRUE to requestw PM to paint the window background
2921 // in SYSCLR_WINDOW. We don't really want that
2922 //
2923 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2924 mResult = (MRESULT)(FALSE);
2925 break;
2926
cdf1e714
DW
2927 // the return value for this message is ignored
2928 case WM_SYSCOLORCHANGE:
61243a51 2929 bProcessed = HandleSysColorChange();
cdf1e714
DW
2930 break;
2931
61243a51
DW
2932 case WM_REALIZEPALETTE:
2933 bProcessed = HandlePaletteChanged();
cdf1e714
DW
2934 break;
2935
61243a51
DW
2936 // move all drag and drops to wxDrg
2937 case WM_ENDDRAG:
2938 bProcessed = HandleEndDrag(wParam);
cdf1e714
DW
2939 break;
2940
61243a51
DW
2941 case WM_INITDLG:
2942 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
cdf1e714 2943
61243a51 2944 if ( bProcessed )
cdf1e714
DW
2945 {
2946 // we never set focus from here
272ebf16 2947 mResult = (MRESULT)FALSE;
cdf1e714
DW
2948 }
2949 break;
2950
61243a51
DW
2951 // wxFrame specific message
2952 case WM_MINMAXFRAME:
f6bcfd97 2953 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
cdf1e714
DW
2954 break;
2955
61243a51
DW
2956 case WM_SYSVALUECHANGED:
2957 // TODO: do something
e604d44b 2958 mResult = (MRESULT)TRUE;
cdf1e714
DW
2959 break;
2960
61243a51
DW
2961 //
2962 // Comparable to WM_SETPOINTER for windows, only for just controls
2963 //
2964 case WM_CONTROLPOINTER:
2965 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2966 ,(HWND)lParam // Cursor Handle
2967 );
2968 if (bProcessed )
cdf1e714 2969 {
61243a51
DW
2970 //
2971 // Returning TRUE stops the DefWindowProc() from further
cdf1e714
DW
2972 // processing this message - exactly what we need because we've
2973 // just set the cursor.
61243a51 2974 //
e604d44b 2975 mResult = (MRESULT)TRUE;
cdf1e714
DW
2976 }
2977 break;
c82be69b
JS
2978
2979#if wxUSE_MENUS_NATIVE
2980 case WM_MENUEND:
2981 if (wxCurrentPopupMenu)
2982 {
2983 if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
2984 {
2985 // Break out of msg loop in DoPopupMenu
2986 ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
2987 }
2988 }
2989 break;
2990#endif // wxUSE_MENUS_NATIVE
2991
cdf1e714 2992 }
61243a51 2993 if (!bProcessed)
cdf1e714
DW
2994 {
2995#ifdef __WXDEBUG__
2996 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
61243a51 2997 wxGetMessageName(uMsg));
cdf1e714 2998#endif // __WXDEBUG__
d08f23a7
DW
2999 if (IsKindOf(CLASSINFO(wxFrame)))
3000 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
1b086de1
DW
3001 else if (IsKindOf(CLASSINFO(wxDialog)))
3002 mResult = ::WinDefDlgProc( m_hWnd, uMsg, wParam, lParam);
d08f23a7
DW
3003 else
3004 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
cdf1e714 3005 }
e604d44b 3006 return mResult;
0367c1c0 3007} // end of wxWindowOS2::OS2WindowProc
cdf1e714 3008
2461cfa0
SN
3009// ----------------------------------------------------------------------------
3010// wxWindow <-> HWND map
3011// ----------------------------------------------------------------------------
3012
3013wxWinHashTable *wxWinHandleHash = NULL;
3014
61243a51
DW
3015wxWindow* wxFindWinFromHandle(
3016 WXHWND hWnd
3017)
cdf1e714 3018{
2461cfa0 3019 return (wxWindow *)wxWinHandleHash->Get((long)hWnd);
61243a51 3020} // end of wxFindWinFromHandle
cdf1e714 3021
61243a51
DW
3022void wxAssociateWinWithHandle(
3023 HWND hWnd
19193a2c 3024, wxWindowOS2* pWin
61243a51 3025)
cdf1e714 3026{
61243a51
DW
3027 //
3028 // Adding NULL hWnd is (first) surely a result of an error and
cdf1e714 3029 // (secondly) breaks menu command processing
61243a51 3030 //
cdf1e714
DW
3031 wxCHECK_RET( hWnd != (HWND)NULL,
3032 wxT("attempt to add a NULL hWnd to window list ignored") );
3033
3034
61243a51
DW
3035 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
3036
3037 if (pOldWin && (pOldWin != pWin))
cdf1e714 3038 {
61243a51 3039 wxString str(pWin->GetClassInfo()->GetClassName());
0fba44b4
DW
3040
3041 wxLogError( _T("Bug! Found existing HWND %X for new window of class %s")
61243a51 3042 ,(int)hWnd
0fba44b4 3043 ,str.c_str()
61243a51 3044 );
cdf1e714 3045 }
61243a51 3046 else if (!pOldWin)
cdf1e714 3047 {
2461cfa0
SN
3048 wxWinHandleHash->Put( (long)hWnd
3049 ,(wxWindow *)pWin
3050 );
cdf1e714 3051 }
61243a51 3052} // end of wxAssociateWinWithHandle
cdf1e714 3053
61243a51 3054void wxRemoveHandleAssociation(
19193a2c 3055 wxWindowOS2* pWin
61243a51 3056)
cdf1e714 3057{
2461cfa0 3058 wxWinHandleHash->Delete((long)pWin->GetHWND());
61243a51 3059} // end of wxRemoveHandleAssociation
cdf1e714 3060
61243a51 3061//
cdf1e714
DW
3062// Default destroyer - override if you destroy it in some other way
3063// (e.g. with MDI child windows)
61243a51 3064//
0367c1c0 3065void wxWindowOS2::OS2DestroyWindow()
cdf1e714
DW
3066{
3067}
3068
f9efbe3a
DW
3069bool wxWindowOS2::OS2GetCreateWindowCoords(
3070 const wxPoint& rPos
3071, const wxSize& rSize
3072, int& rnX
3073, int& rnY
3074, int& rnWidth
3075, int& rnHeight
3076) const
3077{
3078 bool bNonDefault = FALSE;
d697657f
DW
3079 static const int DEFAULT_Y = 200;
3080 static const int DEFAULT_H = 250;
f9efbe3a
DW
3081
3082 if (rPos.x == -1)
3083 {
f9efbe3a
DW
3084 rnX = rnY = CW_USEDEFAULT;
3085 }
3086 else
3087 {
3088 rnX = rPos.x;
d697657f 3089 rnY = rPos.y == -1 ? DEFAULT_Y : rPos.y;
f9efbe3a
DW
3090 bNonDefault = TRUE;
3091 }
3092 if (rSize.x == -1)
3093 {
f9efbe3a
DW
3094 rnWidth = rnHeight = CW_USEDEFAULT;
3095 }
3096 else
3097 {
3098 rnWidth = rSize.x;
d697657f 3099 rnHeight = rSize.y == -1 ? DEFAULT_H : rSize.y;
f9efbe3a
DW
3100 bNonDefault = TRUE;
3101 }
3102 return bNonDefault;
3103} // end of wxWindowOS2::OS2GetCreateWindowCoords
3104
6ed98c6a
DW
3105WXHWND wxWindowOS2::OS2GetParent() const
3106{
3107 return m_parent ? m_parent->GetHWND() : NULL;
3108}
3109
0367c1c0 3110bool wxWindowOS2::OS2Create(
5d44b24e 3111 PSZ zClass
0fba44b4 3112, const wxChar* zTitle
61243a51 3113, WXDWORD dwStyle
5d44b24e
DW
3114, const wxPoint& rPos
3115, const wxSize& rSize
f23208ca 3116, void* pCtlData
008089f6 3117, WXDWORD dwExStyle
5d44b24e 3118, bool bIsChild
61243a51
DW
3119)
3120{
914589c2
DW
3121 ERRORID vError;
3122 wxString sError;
5d44b24e
DW
3123 int nX = 0L;
3124 int nY = 0L;
3125 int nWidth = 0L;
3126 int nHeight = 0L;
5d44b24e
DW
3127 long lControlId = 0L;
3128 wxWindowCreationHook vHook(this);
3129 wxString sClassName((wxChar*)zClass);
3130
3131 OS2GetCreateWindowCoords( rPos
3132 ,rSize
3133 ,nX
3134 ,nY
3135 ,nWidth
3136 ,nHeight
3137 );
3138
5d44b24e 3139 if (bIsChild)
cdf1e714 3140 {
5d44b24e
DW
3141 lControlId = GetId();
3142 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
cdf1e714 3143 {
5d44b24e 3144 dwStyle |= WS_CLIPSIBLINGS;
cdf1e714
DW
3145 }
3146 }
cd212ee4 3147 //
5d44b24e
DW
3148 // For each class "Foo" we have we also have "FooNR" ("no repaint") class
3149 // which is the same but without CS_[HV]REDRAW class styles so using it
3150 // ensures that the window is not fully repainted on each resize
e604d44b 3151 //
020172f6 3152 if (!HasFlag(wxFULL_REPAINT_ON_RESIZE))
51c1d535 3153 {
5d44b24e
DW
3154 sClassName += wxT("NR");
3155 }
6ed98c6a
DW
3156 m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
3157 ,(PSZ)sClassName.c_str()
0fba44b4 3158 ,(PSZ)(zTitle ? zTitle : wxEmptyString)
6ed98c6a
DW
3159 ,(ULONG)dwStyle
3160 ,(LONG)0L
3161 ,(LONG)0L
3162 ,(LONG)0L
3163 ,(LONG)0L
3164 ,NULLHANDLE
3165 ,HWND_TOP
3166 ,(ULONG)lControlId
3167 ,pCtlData
3168 ,NULL
3169 );
5d44b24e
DW
3170 if (!m_hWnd)
3171 {
3172 vError = ::WinGetLastError(wxGetInstance());
3173 sError = wxPMErrorToStr(vError);
3174 return FALSE;
51c1d535 3175 }
5d44b24e 3176 SubclassWin(m_hWnd);
a756f210 3177 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
4a46a5df 3178
0fba44b4 3179 m_backgroundColour.Set(wxString(wxT("GREY")));
4a46a5df
DW
3180
3181 LONG lColor = (LONG)m_backgroundColour.GetPixel();
3182
3183 if (!::WinSetPresParam( m_hWnd
3184 ,PP_BACKGROUNDCOLOR
3185 ,sizeof(LONG)
3186 ,(PVOID)&lColor
3187 ))
3188 {
3189 vError = ::WinGetLastError(vHabmain);
3190 sError = wxPMErrorToStr(vError);
0fba44b4 3191 wxLogError(_T("Error creating frame. Error: %s\n"), sError.c_str());
4a46a5df
DW
3192 return FALSE;
3193 }
5d44b24e
DW
3194 SetSize( nX
3195 ,nY
3196 ,nWidth
3197 ,nHeight
3198 );
cdf1e714 3199 return TRUE;
5d44b24e 3200} // end of WinGuiBase_Window::OS2Create
cdf1e714
DW
3201
3202// ===========================================================================
3203// OS2 PM message handlers
3204// ===========================================================================
3205
3206// ---------------------------------------------------------------------------
61243a51 3207// window creation/destruction
cdf1e714
DW
3208// ---------------------------------------------------------------------------
3209
0367c1c0 3210bool wxWindowOS2::HandleCreate(
19193a2c 3211 WXLPCREATESTRUCT WXUNUSED(vCs)
61243a51
DW
3212, bool* pbMayCreate
3213)
cdf1e714 3214{
19193a2c 3215 wxWindowCreateEvent vEvent((wxWindow*)this);
cdf1e714 3216
61243a51
DW
3217 (void)GetEventHandler()->ProcessEvent(vEvent);
3218 *pbMayCreate = TRUE;
cdf1e714 3219 return TRUE;
0367c1c0 3220} // end of wxWindowOS2::HandleCreate
cdf1e714 3221
0367c1c0 3222bool wxWindowOS2::HandleDestroy()
cdf1e714 3223{
6e348b12
DW
3224 wxWindowDestroyEvent vEvent((wxWindow*)this);
3225 vEvent.SetId(GetId());
3226 (void)GetEventHandler()->ProcessEvent(vEvent);
61243a51
DW
3227
3228 //
3229 // Delete our drop target if we've got one
3230 //
cdf1e714 3231#if wxUSE_DRAG_AND_DROP
61243a51 3232 if (m_dropTarget != NULL)
cdf1e714 3233 {
cdf1e714
DW
3234 delete m_dropTarget;
3235 m_dropTarget = NULL;
3236 }
3237#endif // wxUSE_DRAG_AND_DROP
3238
61243a51 3239 //
cdf1e714 3240 // WM_DESTROY handled
61243a51 3241 //
cdf1e714 3242 return TRUE;
0367c1c0 3243} // end of wxWindowOS2::HandleDestroy
cdf1e714
DW
3244
3245// ---------------------------------------------------------------------------
3246// activation/focus
3247// ---------------------------------------------------------------------------
0367c1c0 3248void wxWindowOS2::OnSetFocus(
61243a51
DW
3249 wxFocusEvent& rEvent
3250)
cdf1e714 3251{
61243a51 3252 rEvent.Skip();
0367c1c0 3253} // end of wxWindowOS2::OnSetFocus
61243a51 3254
0367c1c0 3255bool wxWindowOS2::HandleActivate(
61243a51
DW
3256 int nState
3257, WXHWND WXUNUSED(hActivate)
3258)
3259{
3260 wxActivateEvent vEvent( wxEVT_ACTIVATE
3261 ,(bool)nState
3262 ,m_windowId
3263 );
3264 vEvent.SetEventObject(this);
3265 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3266} // end of wxWindowOS2::HandleActivate
61243a51 3267
0367c1c0 3268bool wxWindowOS2::HandleSetFocus(
61243a51
DW
3269 WXHWND WXUNUSED(hWnd)
3270)
cdf1e714 3271{
54ffa107
DW
3272 //
3273 // Notify the parent keeping track of focus for the kbd navigation
3274 // purposes that we got it
3275 //
3276 wxChildFocusEvent vEventFocus((wxWindow *)this);
3277 (void)GetEventHandler()->ProcessEvent(vEventFocus);
3278
cdf1e714 3279#if wxUSE_CARET
61243a51 3280 //
cdf1e714 3281 // Deal with caret
61243a51
DW
3282 //
3283 if (m_caret)
cdf1e714
DW
3284 {
3285 m_caret->OnSetFocus();
3286 }
3287#endif // wxUSE_CARET
3288
1bcfc0e1
DW
3289#if wxUSE_TEXTCTRL
3290 // If it's a wxTextCtrl don't send the event as it will be done
3291 // after the control gets to process it from EN_FOCUS handler
3292 if ( wxDynamicCastThis(wxTextCtrl) )
cdf1e714 3293 {
1bcfc0e1 3294 return FALSE;
cdf1e714 3295 }
1bcfc0e1 3296#endif // wxUSE_TEXTCTRL
cdf1e714 3297
61243a51 3298 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
cdf1e714 3299
61243a51
DW
3300 vEvent.SetEventObject(this);
3301 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3302} // end of wxWindowOS2::HandleSetFocus
cdf1e714 3303
0367c1c0 3304bool wxWindowOS2::HandleKillFocus(
a23692f0 3305 WXHWND hWnd
61243a51 3306)
cdf1e714
DW
3307{
3308#if wxUSE_CARET
61243a51 3309 //
cdf1e714 3310 // Deal with caret
61243a51
DW
3311 //
3312 if (m_caret)
cdf1e714
DW
3313 {
3314 m_caret->OnKillFocus();
3315 }
3316#endif // wxUSE_CARET
3317
a23692f0 3318#if wxUSE_TEXTCTRL
f289196b 3319 //
a23692f0
DW
3320 // If it's a wxTextCtrl don't send the event as it will be done
3321 // after the control gets to process it.
3322 //
3323 wxTextCtrl* pCtrl = wxDynamicCastThis(wxTextCtrl);
3324
3325 if (pCtrl)
3326 {
3327 return FALSE;
3328 }
3329#endif
3330
f289196b 3331 //
a23692f0
DW
3332 // Don't send the event when in the process of being deleted. This can
3333 // only cause problems if the event handler tries to access the object.
3334 //
3335 if ( m_isBeingDeleted )
3336 {
3337 return FALSE;
3338 }
3339
61243a51
DW
3340 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
3341 ,m_windowId
3342 );
cdf1e714 3343
61243a51 3344 vEvent.SetEventObject(this);
a23692f0 3345
f289196b 3346 //
a23692f0
DW
3347 // wxFindWinFromHandle() may return NULL, it is ok
3348 //
3349 vEvent.SetWindow(wxFindWinFromHandle(hWnd));
61243a51 3350 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3351} // end of wxWindowOS2::HandleKillFocus
cdf1e714
DW
3352
3353// ---------------------------------------------------------------------------
3354// miscellaneous
3355// ---------------------------------------------------------------------------
3356
0367c1c0 3357bool wxWindowOS2::HandleShow(
61243a51 3358 bool bShow
19193a2c 3359, int WXUNUSED(nStatus)
61243a51 3360)
cdf1e714 3361{
19193a2c 3362 wxShowEvent vEvent(GetId(), bShow);
cdf1e714 3363
687706f5 3364 vEvent.SetEventObject(this);
61243a51 3365 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3366} // end of wxWindowOS2::HandleShow
cdf1e714 3367
0367c1c0 3368bool wxWindowOS2::HandleInitDialog(
61243a51
DW
3369 WXHWND WXUNUSED(hWndFocus)
3370)
cdf1e714 3371{
61243a51 3372 wxInitDialogEvent vEvent(GetId());
cdf1e714 3373
687706f5 3374 vEvent.SetEventObject(this);
61243a51 3375 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3376} // end of wxWindowOS2::HandleInitDialog
cdf1e714 3377
19193a2c 3378bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
cdf1e714 3379{
61243a51 3380 // TODO: We'll handle drag and drop later
cdf1e714
DW
3381 return FALSE;
3382}
3383
0367c1c0 3384bool wxWindowOS2::HandleSetCursor(
19193a2c 3385 USHORT WXUNUSED(vId)
61243a51
DW
3386, WXHWND hPointer
3387)
cdf1e714 3388{
61243a51
DW
3389 //
3390 // Under OS/2 PM this allows the pointer to be changed
3391 // as it passes over a control
3392 //
3393 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
3394 return TRUE;
0367c1c0 3395} // end of wxWindowOS2::HandleSetCursor
cdf1e714
DW
3396
3397// ---------------------------------------------------------------------------
3398// owner drawn stuff
3399// ---------------------------------------------------------------------------
0367c1c0 3400bool wxWindowOS2::OS2OnDrawItem(
61243a51
DW
3401 int vId
3402, WXDRAWITEMSTRUCT* pItemStruct
3403)
cdf1e714 3404{
19193a2c 3405#if wxUSE_OWNER_DRAWN
402e2f7c 3406 wxDC vDc;
61243a51 3407
19193a2c 3408#if wxUSE_MENUS_NATIVE
61243a51 3409 //
402e2f7c 3410 // Is it a menu item?
61243a51 3411 //
402e2f7c
DW
3412 if (vId == 0)
3413 {
5afb9458
DW
3414 ERRORID vError;
3415 wxString sError;
402e2f7c 3416 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
23122f8c
DW
3417 wxFrame* pFrame = (wxFrame*)this;
3418 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
402e2f7c 3419 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
23122f8c
DW
3420 wxRect vRect( pMeasureStruct->rclItem.xLeft
3421 ,pMeasureStruct->rclItem.yBottom
3422 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3423 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3424 );
402e2f7c
DW
3425 vDc.SetHDC( hDC
3426 ,FALSE
3427 );
3428 vDc.SetHPS(pMeasureStruct->hps);
5afb9458 3429 //
77ffb593 3430 // Load the wxWidgets Pallete and set to RGB mode
5afb9458
DW
3431 //
3432 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3433 ,0L
3434 ,LCOLF_CONSECRGB
3435 ,0L
3436 ,(LONG)wxTheColourDatabase->m_nSize
3437 ,(PLONG)wxTheColourDatabase->m_palTable
3438 ))
3439 {
3440 vError = ::WinGetLastError(vHabmain);
3441 sError = wxPMErrorToStr(vError);
0fba44b4 3442 wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
5afb9458
DW
3443 }
3444 //
3445 // Set the color table to RGB mode
3446 //
3447 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3448 ,0L
3449 ,LCOLF_RGB
3450 ,0L
3451 ,0L
3452 ,NULL
3453 ))
3454 {
3455 vError = ::WinGetLastError(vHabmain);
3456 sError = wxPMErrorToStr(vError);
0fba44b4 3457 wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
5afb9458 3458 }
cdf1e714 3459
23122f8c
DW
3460 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3461
3462
3463 int eAction = 0;
3464 int eStatus = 0;
cdf1e714 3465
402e2f7c 3466 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
23122f8c
DW
3467 {
3468 //
3469 // Entire Item needs to be redrawn (either it has reappeared from
3470 // behind another window or is being displayed for the first time
3471 //
402e2f7c 3472 eAction = wxOwnerDrawn::wxODDrawAll;
23122f8c
DW
3473
3474 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3475 {
3476 //
3477 // If it is currently selected we let the system handle it
3478 //
3479 eStatus |= wxOwnerDrawn::wxODSelected;
3480 }
3481 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3482 {
3483 //
3484 // If it is currently checked we draw our own
3485 //
3486 eStatus |= wxOwnerDrawn::wxODChecked;
3487 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3488 }
3489 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3490 {
3491 //
3492 // If it is currently disabled we let the system handle it
3493 //
3494 eStatus |= wxOwnerDrawn::wxODDisabled;
3495 }
3496 //
3497 // Don't really care about framed (indicationg focus) or NoDismiss
3498 //
3499 }
402e2f7c 3500 else
23122f8c 3501 {
5afb9458
DW
3502 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3503 {
3504 eAction = wxOwnerDrawn::wxODDrawAll;
3505 eStatus |= wxOwnerDrawn::wxODSelected;
3506 //
3507 // Keep the system from trying to highlight with its bogus colors
3508 //
3509 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3510 }
3511 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3512 {
3513 eAction = wxOwnerDrawn::wxODDrawAll;
3514 eStatus = 0;
3515 //
3516 // Keep the system from trying to highlight with its bogus colors
3517 //
3518 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3519 }
3520 else
3521 {
3522 //
3523 // For now we don't care about anything else
3524 // just ignore the entire message!
3525 //
3526 return TRUE;
3527 }
23122f8c
DW
3528 }
3529 //
3530 // Now redraw the item
3531 //
45bedfdd
DW
3532 return(pMenuItem->OnDrawItem( vDc
3533 ,vRect
23122f8c
DW
3534 ,(wxOwnerDrawn::wxODAction)eAction
3535 ,(wxOwnerDrawn::wxODStatus)eStatus
45bedfdd 3536 ));
402e2f7c
DW
3537 //
3538 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3539 // the system will do the highlight or fraeming or disabling for us,
3540 // otherwise, we'd have to do it ourselves.
61243a51 3541 //
cdf1e714 3542 }
19193a2c 3543#endif // wxUSE_MENUS_NATIVE
cdf1e714 3544
402e2f7c
DW
3545 wxWindow* pItem = FindItem(vId);
3546
3547 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3548 {
3549 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3550 }
19193a2c
KB
3551#else
3552 vId = vId;
3553 pItemStruct = pItemStruct;
61243a51 3554#endif
402e2f7c 3555 return FALSE;
0367c1c0 3556} // end of wxWindowOS2::OS2OnDrawItem
cdf1e714 3557
f5ea767e 3558long wxWindowOS2::OS2OnMeasureItem(
402e2f7c
DW
3559 int lId
3560, WXMEASUREITEMSTRUCT* pItemStruct
3561)
0e320a79 3562{
19193a2c 3563#if wxUSE_OWNER_DRAWN
402e2f7c
DW
3564 //
3565 // Is it a menu item?
3566 //
45bedfdd 3567 if (lId == 65536) // I really don't like this...has to be a better indicator
cdf1e714 3568 {
4049cc1c 3569 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
45bedfdd 3570 {
4049cc1c
DW
3571 size_t nWidth;
3572 size_t nHeight;
3573 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
45bedfdd
DW
3574 wxFrame* pFrame = (wxFrame*)this;
3575 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
cdf1e714 3576
45bedfdd 3577 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
4049cc1c
DW
3578 nWidth = 0L;
3579 nHeight = 0L;
3580 if (pMenuItem->OnMeasureItem( &nWidth
3581 ,&nHeight
3582 ))
3583 {
f5ea767e
DW
3584 MRESULT mRc;
3585
4049cc1c
DW
3586 pMeasureStruct->rclItem.xRight = nWidth;
3587 pMeasureStruct->rclItem.xLeft = 0L;
3588 pMeasureStruct->rclItem.yTop = nHeight;
3589 pMeasureStruct->rclItem.yBottom = 0L;
f5ea767e
DW
3590 mRc = MRFROM2SHORT(nHeight, nWidth);
3591 return LONGFROMMR(mRc);
4049cc1c 3592 }
f5ea767e 3593 return 0L;
45bedfdd 3594 }
cdf1e714 3595 }
f15b4952 3596 wxWindow* pItem = FindItem(lId);
cdf1e714 3597
402e2f7c 3598 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
cdf1e714 3599 {
1de4baa3
DW
3600 OWNERITEM vItem;
3601
3602 vItem.idItem = (LONG)pItemStruct;
3603 return ((wxControl *)pItem)->OS2OnMeasure((WXMEASUREITEMSTRUCT*)&vItem);
cdf1e714 3604 }
19193a2c
KB
3605#else
3606 lId = lId;
3607 pItemStruct = pItemStruct;
3608#endif // wxUSE_OWNER_DRAWN
cdf1e714 3609 return FALSE;
0e320a79
DW
3610}
3611
cdf1e714
DW
3612// ---------------------------------------------------------------------------
3613// colours and palettes
3614// ---------------------------------------------------------------------------
849949b1 3615
0367c1c0 3616bool wxWindowOS2::HandleSysColorChange()
0e320a79 3617{
61243a51 3618 wxSysColourChangedEvent vEvent;
cdf1e714 3619
61243a51
DW
3620 vEvent.SetEventObject(this);
3621 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3622} // end of wxWindowOS2::HandleSysColorChange
0e320a79 3623
0367c1c0 3624bool wxWindowOS2::HandleCtlColor(
19193a2c 3625 WXHBRUSH* WXUNUSED(phBrush)
61243a51 3626)
0e320a79 3627{
61243a51
DW
3628 //
3629 // Not much provided with message. So not sure I can do anything with it
3630 //
3631 return TRUE;
0367c1c0 3632} // end of wxWindowOS2::HandleCtlColor
cdf1e714 3633
0e320a79 3634
cdf1e714 3635// Define for each class of dialog and control
19193a2c
KB
3636WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
3637 WXHWND WXUNUSED(hWnd),
3638 WXUINT WXUNUSED(nCtlColor),
3639 WXUINT WXUNUSED(message),
3640 WXWPARAM WXUNUSED(wParam),
3641 WXLPARAM WXUNUSED(lParam))
0e320a79 3642{
cdf1e714 3643 return (WXHBRUSH)0;
0e320a79
DW
3644}
3645
0367c1c0 3646bool wxWindowOS2::HandlePaletteChanged()
0e320a79 3647{
61243a51
DW
3648 // need to set this to something first
3649 WXHWND hWndPalChange = NULLHANDLE;
cdf1e714 3650
61243a51
DW
3651 wxPaletteChangedEvent vEvent(GetId());
3652
3653 vEvent.SetEventObject(this);
3654 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
0e320a79 3655
61243a51 3656 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3657} // end of wxWindowOS2::HandlePaletteChanged
61243a51 3658
61243a51 3659//
cdf1e714 3660// Responds to colour changes: passes event on to children.
61243a51 3661//
0367c1c0 3662void wxWindowOS2::OnSysColourChanged(
61243a51
DW
3663 wxSysColourChangedEvent& rEvent
3664)
0e320a79 3665{
2461cfa0 3666 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
61243a51 3667
2461cfa0 3668 while (node)
cdf1e714 3669 {
61243a51 3670 //
cdf1e714 3671 // Only propagate to non-top-level windows
61243a51 3672 //
2461cfa0 3673 wxWindow* pWin = (wxWindow *)node->GetData();
61243a51
DW
3674
3675 if (pWin->GetParent())
cdf1e714 3676 {
61243a51 3677 wxSysColourChangedEvent vEvent;
cdf1e714 3678
687706f5 3679 rEvent.SetEventObject(pWin);
61243a51
DW
3680 pWin->GetEventHandler()->ProcessEvent(vEvent);
3681 }
2461cfa0 3682 node = node->GetNext();
cdf1e714 3683 }
0367c1c0 3684} // end of wxWindowOS2::OnSysColourChanged
0e320a79 3685
cdf1e714
DW
3686// ---------------------------------------------------------------------------
3687// painting
3688// ---------------------------------------------------------------------------
3689
b45bca40
DW
3690void wxWindow::OnPaint (
3691 wxPaintEvent& rEvent
3692)
3693{
3694 HDC hDC = (HDC)wxPaintDC::FindDCInCache((wxWindow*) rEvent.GetEventObject());
3695
3696 if (hDC != 0)
3697 {
3698 OS2DefWindowProc( (WXUINT)WM_PAINT
3699 ,(WXWPARAM)hDC
3700 ,(WXLPARAM)0
3701 );
3702 }
3703} // end of wxWindow::OnPaint
3704
0367c1c0 3705bool wxWindowOS2::HandlePaint()
0e320a79 3706{
19193a2c
KB
3707 HRGN hRgn;
3708 wxPaintEvent vEvent(m_windowId);
40bd6154 3709 HPS hPS;
19193a2c
KB
3710 bool bProcessed;
3711
3712 // Create empty region
3713 // TODO: get HPS somewhere else if possible
3714 hPS = ::WinGetPS(GetHwnd());
3715 hRgn = ::GpiCreateRegion(hPS, 0, NULL);
61243a51 3716
19193a2c 3717 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
61243a51
DW
3718 {
3719 wxLogLastError("CreateRectRgn");
3720 return FALSE;
3721 }
7e99520b 3722
5d826f60
SN
3723 // Get all the rectangles from the region, convert the individual
3724 // rectangles to "the other" coordinate system and reassemble a
3725 // region from the rectangles, to be feed into m_updateRegion.
3726 //
3727 // FIXME: This is a bad hack since OS/2 API specifies that rectangles
3728 // passed into GpiSetRegion must not have Bottom > Top,
3729 // however, at first sight, it _seems_ to work nonetheless.
3730 //
3731 RGNRECT vRgnData;
3732 PRECTL pUpdateRects = NULL;
3733 vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
3734 if (::GpiQueryRegionRects( hPS // Pres space
3735 ,hRgn // Handle of region to query
3736 ,NULL // Return all RECTs
3737 ,&vRgnData // Will contain number or RECTs in region
3738 ,NULL // NULL to return number of RECTs
3739 ))
3740 {
3741 pUpdateRects = new RECTL[vRgnData.crcReturned];
3742 vRgnData.crc = vRgnData.crcReturned;
3743 vRgnData.ircStart = 1;
3744 if (::GpiQueryRegionRects( hPS // Pres space of source
3745 ,hRgn // Handle of source region
3746 ,NULL // Return all RECTs
3747 ,&vRgnData // Operations set to return rects
3748 ,pUpdateRects // Will contain the actual RECTS
3749 ))
3750 {
3751 int height;
3752 RECT vRect;
3753 ::WinQueryWindowRect(GetHwnd(), &vRect);
3754 height = vRect.yTop;
3755
3756 for(size_t i = 0; i < vRgnData.crc; i++)
3757 {
3758 int rectHeight;
3759 rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
3760 pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
3761 pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
3762 }
3763 ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
3764 delete [] pUpdateRects;
3765 }
3766 }
3767
19193a2c
KB
3768 m_updateRegion = wxRegion(hRgn, hPS);
3769
61243a51 3770 vEvent.SetEventObject(this);
19193a2c
KB
3771 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
3772
524d72c4
DW
3773 if (!bProcessed &&
3774 IsKindOf(CLASSINFO(wxPanel)) &&
3775 GetChildren().GetCount() == 0
3776 )
3777 {
3778 //
3779 // OS/2 needs to process this right here, not by the default proc
f289196b
DW
3780 // Window's default proc correctly paints everything, OS/2 does not.
3781 // For decorative panels that typically have no children, we draw
3782 // borders.
524d72c4
DW
3783 //
3784 HPS hPS;
3785 RECTL vRect;
524d72c4
DW
3786
3787 hPS = ::WinBeginPaint( GetHwnd()
3788 ,NULLHANDLE
3789 ,&vRect
3790 );
3791 if(hPS)
3792 {
3793 ::GpiCreateLogColorTable( hPS
3794 ,0L
3795 ,LCOLF_CONSECRGB
3796 ,0L
3797 ,(LONG)wxTheColourDatabase->m_nSize
3798 ,(PLONG)wxTheColourDatabase->m_palTable
3799 );
3800 ::GpiCreateLogColorTable( hPS
3801 ,0L
3802 ,LCOLF_RGB
3803 ,0L
3804 ,0L
3805 ,NULL
3806 );
1de4baa3 3807 if (::WinIsWindowVisible(GetHWND()))
f289196b 3808 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
1de4baa3
DW
3809 if (m_dwExStyle)
3810 {
3811 LINEBUNDLE vLineBundle;
3812
3813 vLineBundle.lColor = 0x00000000; // Black
3814 vLineBundle.usMixMode = FM_OVERPAINT;
3815 vLineBundle.fxWidth = 1;
3816 vLineBundle.lGeomWidth = 1;
3817 vLineBundle.usType = LINETYPE_SOLID;
3818 vLineBundle.usEnd = 0;
3819 vLineBundle.usJoin = 0;
3820 ::GpiSetAttrs( hPS
3821 ,PRIM_LINE
3822 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
3823 ,0L
3824 ,&vLineBundle
3825 );
3826 ::WinQueryWindowRect(GetHwnd(), &vRect);
3827 wxDrawBorder( hPS
3828 ,vRect
3829 ,m_dwExStyle
3830 );
524d72c4 3831 }
524d72c4 3832 }
f289196b 3833 ::WinEndPaint(hPS);
524d72c4
DW
3834 bProcessed = TRUE;
3835 }
f289196b
DW
3836 else if (!bProcessed &&
3837 IsKindOf(CLASSINFO(wxPanel))
3838 )
3839 {
3840 //
3841 // Panel with children, usually fills a frame client so no borders.
3842 //
3843 HPS hPS;
3844 RECTL vRect;
524d72c4 3845
f289196b
DW
3846 hPS = ::WinBeginPaint( GetHwnd()
3847 ,NULLHANDLE
3848 ,&vRect
3849 );
3850 if(hPS)
3851 {
3852 ::GpiCreateLogColorTable( hPS
3853 ,0L
3854 ,LCOLF_CONSECRGB
3855 ,0L
3856 ,(LONG)wxTheColourDatabase->m_nSize
3857 ,(PLONG)wxTheColourDatabase->m_palTable
3858 );
3859 ::GpiCreateLogColorTable( hPS
3860 ,0L
3861 ,LCOLF_RGB
3862 ,0L
3863 ,0L
3864 ,NULL
3865 );
3866
1de4baa3 3867 if (::WinIsWindowVisible(GetHWND()))
f289196b
DW
3868 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3869 }
3870 ::WinEndPaint(hPS);
3871 bProcessed = TRUE;
3872 }
524d72c4 3873 return bProcessed;
0367c1c0 3874} // end of wxWindowOS2::HandlePaint
0e320a79 3875
0367c1c0 3876bool wxWindowOS2::HandleEraseBkgnd(
8d854fa9
DW
3877 WXHDC hDC
3878)
0e320a79 3879{
8d854fa9 3880 SWP vSwp;
19193a2c 3881 bool rc;
8d854fa9
DW
3882
3883 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3884 if (vSwp.fl & SWP_MINIMIZE)
61243a51 3885 return TRUE;
cdf1e714 3886
8d854fa9
DW
3887 wxDC vDC;
3888
3889 vDC.m_hPS = (HPS)hDC; // this is really a PS
19193a2c 3890 vDC.SetWindow((wxWindow*)this);
8d854fa9 3891 vDC.BeginDrawing();
cdf1e714 3892
8d854fa9
DW
3893 wxEraseEvent vEvent(m_windowId, &vDC);
3894
3895 vEvent.SetEventObject(this);
cdf1e714 3896
19193a2c 3897 rc = GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3898
8d854fa9
DW
3899 vDC.EndDrawing();
3900 vDC.m_hPS = NULLHANDLE;
61243a51 3901 return TRUE;
0367c1c0 3902} // end of wxWindowOS2::HandleEraseBkgnd
cdf1e714 3903
0367c1c0 3904void wxWindowOS2::OnEraseBackground(
61243a51
DW
3905 wxEraseEvent& rEvent
3906)
0e320a79 3907{
8d854fa9
DW
3908 RECTL vRect;
3909 HPS hPS = rEvent.m_dc->m_hPS;
19193a2c
KB
3910 APIRET rc;
3911 LONG lColor = m_backgroundColour.GetPixel();
8d854fa9 3912
19193a2c
KB
3913 rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
3914 rc = ::WinFillRect(hPS, &vRect, lColor);
0367c1c0 3915} // end of wxWindowOS2::OnEraseBackground
0e320a79 3916
cdf1e714
DW
3917// ---------------------------------------------------------------------------
3918// moving and resizing
3919// ---------------------------------------------------------------------------
0e320a79 3920
0367c1c0 3921bool wxWindowOS2::HandleMinimize()
0e320a79 3922{
61243a51 3923 wxIconizeEvent vEvent(m_windowId);
cdf1e714 3924
61243a51
DW
3925 vEvent.SetEventObject(this);
3926 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3927} // end of wxWindowOS2::HandleMinimize
0e320a79 3928
0367c1c0 3929bool wxWindowOS2::HandleMaximize()
0e320a79 3930{
61243a51 3931 wxMaximizeEvent vEvent(m_windowId);
cdf1e714 3932
61243a51
DW
3933 vEvent.SetEventObject(this);
3934 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3935} // end of wxWindowOS2::HandleMaximize
0e320a79 3936
0367c1c0 3937bool wxWindowOS2::HandleMove(
61243a51
DW
3938 int nX
3939, int nY
3940)
0e320a79 3941{
19193a2c 3942 wxMoveEvent vEvent(wxPoint(nX, nY), m_windowId);
cdf1e714 3943
61243a51
DW
3944 vEvent.SetEventObject(this);
3945 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3946} // end of wxWindowOS2::HandleMove
0e320a79 3947
0367c1c0 3948bool wxWindowOS2::HandleSize(
61243a51
DW
3949 int nWidth
3950, int nHeight
3951, WXUINT WXUNUSED(nFlag)
3952)
0e320a79 3953{
19193a2c 3954 wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
cdf1e714 3955
61243a51
DW
3956 vEvent.SetEventObject(this);
3957 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3958} // end of wxWindowOS2::HandleSize
0e320a79 3959
0367c1c0 3960bool wxWindowOS2::HandleGetMinMaxInfo(
61243a51
DW
3961 PSWP pSwp
3962)
0e320a79 3963{
61243a51 3964 POINTL vPoint;
cdf1e714 3965
61243a51 3966 switch(pSwp->fl)
cdf1e714 3967 {
61243a51
DW
3968 case SWP_MAXIMIZE:
3969 ::WinGetMaxPosition(GetHwnd(), pSwp);
3970 m_maxWidth = pSwp->cx;
3971 m_maxHeight = pSwp->cy;
3972 break;
cdf1e714 3973
61243a51
DW
3974 case SWP_MINIMIZE:
3975 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3976 m_minWidth = pSwp->cx;
3977 m_minHeight = pSwp->cy;
3978 break;
cdf1e714 3979
61243a51
DW
3980 default:
3981 return FALSE;
cdf1e714 3982 }
61243a51 3983 return TRUE;
0367c1c0 3984} // end of wxWindowOS2::HandleGetMinMaxInfo
0e320a79 3985
cdf1e714
DW
3986// ---------------------------------------------------------------------------
3987// command messages
3988// ---------------------------------------------------------------------------
0367c1c0 3989bool wxWindowOS2::HandleCommand(
61243a51
DW
3990 WXWORD wId
3991, WXWORD wCmd
3992, WXHWND hControl
3993)
0e320a79 3994{
19193a2c 3995#if wxUSE_MENUS_NATIVE
61243a51 3996 if (wxCurrentPopupMenu)
0e320a79 3997 {
61243a51 3998 wxMenu* pPopupMenu = wxCurrentPopupMenu;
0e320a79 3999
61243a51
DW
4000 wxCurrentPopupMenu = NULL;
4001 return pPopupMenu->OS2Command(wCmd, wId);
cdf1e714 4002 }
19193a2c 4003#endif // wxUSE_MENUS_NATIVE
0e320a79 4004
61243a51
DW
4005 wxWindow* pWin = FindItem(wId);
4006
4007 if (!pWin)
cdf1e714 4008 {
61243a51 4009 pWin = wxFindWinFromHandle(hControl);
0e320a79 4010 }
cdf1e714 4011
61243a51 4012 if (pWin)
19193a2c
KB
4013 return pWin->OS2Command(wCmd, wId);
4014
cdf1e714 4015 return FALSE;
0367c1c0 4016} // end of wxWindowOS2::HandleCommand
de44a9f0 4017
0367c1c0 4018bool wxWindowOS2::HandleSysCommand(
61243a51 4019 WXWPARAM wParam
19193a2c 4020, WXLPARAM WXUNUSED(lParam)
61243a51 4021)
0e320a79 4022{
61243a51
DW
4023 //
4024 // 4 bits are reserved
4025 //
4026 switch (SHORT1FROMMP(wParam))
4027 {
4028 case SC_MAXIMIZE:
4029 return HandleMaximize();
4030
4031 case SC_MINIMIZE:
4032 return HandleMinimize();
4033 }
cdf1e714 4034 return FALSE;
0367c1c0 4035} // end of wxWindowOS2::HandleSysCommand
cdf1e714
DW
4036
4037// ---------------------------------------------------------------------------
4038// mouse events
4039// ---------------------------------------------------------------------------
19193a2c 4040//TODO!!! check against MSW
0367c1c0 4041void wxWindowOS2::InitMouseEvent(
61243a51
DW
4042 wxMouseEvent& rEvent
4043, int nX
4044, int nY
4045, WXUINT uFlags
4046)
cdf1e714 4047{
8d902dd6
SN
4048 int nHeight;
4049 DoGetSize(0, &nHeight);
61243a51 4050 rEvent.m_x = nX;
77ffb593 4051 // Convert to wxWidgets standard coordinate system!
8d902dd6
SN
4052 rEvent.m_y = nHeight - nY;
4053 rEvent.m_shiftDown = ((uFlags & KC_SHIFT) != 0);
4054 rEvent.m_controlDown = ((uFlags & KC_CTRL) != 0);
4055 rEvent.m_altDown = ((uFlags & KC_ALT) != 0);
4056 rEvent.m_leftDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
4057 0x8000) != 0;
4058 rEvent.m_middleDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &
4059 0x8000) != 0;
4060 rEvent.m_rightDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
4061 0x8000) != 0;
61243a51 4062 rEvent.SetTimestamp(s_currentMsg.time);
687706f5 4063 rEvent.SetEventObject(this);
6ed98c6a 4064 rEvent.SetId(GetId());
cdf1e714
DW
4065
4066#if wxUSE_MOUSEEVENT_HACK
61243a51
DW
4067 m_lastMouseX = nX;
4068 m_lastMouseY = nY;
4069 m_lastMouseEvent = rEvent.GetEventType();
cdf1e714 4070#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 4071} // end of wxWindowOS2::InitMouseEvent
0e320a79 4072
0367c1c0 4073bool wxWindowOS2::HandleMouseEvent(
61243a51
DW
4074 WXUINT uMsg
4075, int nX
4076, int nY
4077, WXUINT uFlags
4078)
0e320a79 4079{
b389a12d
DW
4080 bool bProcessed = FALSE;
4081
61243a51
DW
4082 //
4083 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
c82be69b 4084 // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
cdf1e714
DW
4085 // from the message id and take the value in the table to get wxWin event
4086 // id
61243a51 4087 //
cdf1e714
DW
4088 static const wxEventType eventsMouse[] =
4089 {
4090 wxEVT_MOTION,
4091 wxEVT_LEFT_DOWN,
4092 wxEVT_LEFT_UP,
4093 wxEVT_LEFT_DCLICK,
4094 wxEVT_RIGHT_DOWN,
4095 wxEVT_RIGHT_UP,
4096 wxEVT_RIGHT_DCLICK,
4097 wxEVT_MIDDLE_DOWN,
4098 wxEVT_MIDDLE_UP,
4099 wxEVT_MIDDLE_DCLICK
4100 };
4101
c82be69b
JS
4102 // Bounds check
4103 if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
b389a12d 4104 {
c82be69b 4105 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
b389a12d 4106
c82be69b
JS
4107 InitMouseEvent( vEvent
4108 ,nX
4109 ,nY
4110 ,uFlags
4111 );
4112
4113 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
4114 if (!bProcessed)
b389a12d 4115 {
c82be69b
JS
4116 HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
4117
4118 if (hCursor != NULLHANDLE)
4119 {
4120 ::WinSetPointer(HWND_DESKTOP, hCursor);
4121 bProcessed = TRUE;
4122 }
b389a12d
DW
4123 }
4124 }
c82be69b 4125 return bProcessed;
0367c1c0 4126} // end of wxWindowOS2::HandleMouseEvent
61243a51 4127
0367c1c0 4128bool wxWindowOS2::HandleMouseMove(
61243a51
DW
4129 int nX
4130, int nY
4131, WXUINT uFlags
4132)
0e320a79 4133{
61243a51 4134 if (!m_bMouseInWindow)
cdf1e714 4135 {
61243a51 4136 //
cdf1e714 4137 // Generate an ENTER event
61243a51 4138 //
776d87d5 4139 m_bMouseInWindow = TRUE;
cdf1e714 4140
61243a51 4141 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
cdf1e714 4142
61243a51
DW
4143 InitMouseEvent( vEvent
4144 ,nX
4145 ,nY
4146 ,uFlags
4147 );
cdf1e714 4148
61243a51 4149 (void)GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 4150 }
61243a51
DW
4151 return HandleMouseEvent( WM_MOUSEMOVE
4152 ,nX
4153 ,nY
4154 ,uFlags
4155 );
0367c1c0 4156} // end of wxWindowOS2::HandleMouseMove
0e320a79 4157
cdf1e714
DW
4158// ---------------------------------------------------------------------------
4159// keyboard handling
4160// ---------------------------------------------------------------------------
4161
61243a51
DW
4162//
4163// Create the key event of the given type for the given key - used by
4164// HandleChar and HandleKeyDown/Up
4165//
0367c1c0 4166wxKeyEvent wxWindowOS2::CreateKeyEvent(
61243a51
DW
4167 wxEventType eType
4168, int nId
4169, WXLPARAM lParam
a086de98 4170, WXWPARAM wParam
61243a51
DW
4171) const
4172{
4173 wxKeyEvent vEvent(eType);
4174
4175 vEvent.SetId(GetId());
4176 vEvent.m_shiftDown = IsShiftDown();
4177 vEvent.m_controlDown = IsCtrlDown();
4178 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
4179
687706f5 4180 vEvent.SetEventObject((wxWindow *)this); // const_cast
61243a51 4181 vEvent.m_keyCode = nId;
a086de98
DW
4182 vEvent.m_rawCode = (wxUint32)wParam;
4183 vEvent.m_rawFlags = (wxUint32)lParam;
61243a51
DW
4184 vEvent.SetTimestamp(s_currentMsg.time);
4185
4186 //
4187 // Translate the position to client coords
4188 //
4189 POINTL vPoint;
4190 RECTL vRect;
4191
4192 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
4193 ::WinQueryWindowRect( GetHwnd()
4194 ,&vRect
4195 );
4196
4197 vPoint.x -= vRect.xLeft;
4198 vPoint.y -= vRect.yBottom;
4199
4200 vEvent.m_x = vPoint.x;
4201 vEvent.m_y = vPoint.y;
4202
4203 return vEvent;
0367c1c0 4204} // end of wxWindowOS2::CreateKeyEvent
61243a51
DW
4205
4206//
cdf1e714
DW
4207// isASCII is TRUE only when we're called from WM_CHAR handler and not from
4208// WM_KEYDOWN one
61243a51 4209//
0367c1c0 4210bool wxWindowOS2::HandleChar(
598d8cac 4211 WXWPARAM wParam
61243a51
DW
4212, WXLPARAM lParam
4213, bool isASCII
4214)
86de7616 4215{
61243a51
DW
4216 bool bCtrlDown = FALSE;
4217 int vId;
4218
3437f881
DW
4219 if (m_bLastKeydownProcessed)
4220 {
4221 //
4222 // The key was handled in the EVT_KEY_DOWN. Handling a key in an
4223 // EVT_KEY_DOWN handler is meant, by design, to prevent EVT_CHARs
4224 // from happening, so just bail out at this point.
4225 //
4226 m_bLastKeydownProcessed = FALSE;
4227 return TRUE;
4228 }
61243a51
DW
4229 if (isASCII)
4230 {
4231 //
a23692f0
DW
4232 // If 1 -> 26, translate to either special keycode or just set
4233 // ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
4234 // ControlDown() == TRUE.
61243a51 4235 //
1de4baa3 4236 vId = SHORT1FROMMP(lParam);
61243a51
DW
4237 if ((vId > 0) && (vId < 27))
4238 {
4239 switch (vId)
4240 {
4241 case 13:
4242 vId = WXK_RETURN;
4243 break;
4244
4245 case 8:
4246 vId = WXK_BACK;
4247 break;
4248
4249 case 9:
4250 vId = WXK_TAB;
4251 break;
4252
4253 default:
4254 bCtrlDown = TRUE;
a23692f0 4255 break;
61243a51
DW
4256 }
4257 }
4258 }
a086de98 4259 else // we're called from WM_KEYDOWN
61243a51 4260 {
1de4baa3 4261 vId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
a086de98
DW
4262 if (vId == 0)
4263 return FALSE;
61243a51
DW
4264 }
4265
a086de98 4266 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
61243a51
DW
4267 ,vId
4268 ,lParam
4269 ));
4270
a086de98
DW
4271 if (bCtrlDown)
4272 {
4273 vEvent.m_controlDown = TRUE;
61243a51 4274 }
a086de98 4275 return (GetEventHandler()->ProcessEvent(vEvent));
cdf1e714 4276}
86de7616 4277
0367c1c0 4278bool wxWindowOS2::HandleKeyDown(
a086de98 4279 WXWPARAM wParam
61243a51
DW
4280, WXLPARAM lParam
4281)
cdf1e714 4282{
1de4baa3 4283 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
86de7616 4284
61243a51
DW
4285 if (!nId)
4286 {
4287 //
4288 // Normal ASCII char
4289 //
1de4baa3 4290 nId = SHORT1FROMMP(lParam);
61243a51
DW
4291 }
4292
4293 if (nId != -1)
4294 {
4295 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
4296 ,nId
a086de98
DW
4297 ,(MPARAM)lParam
4298 ,(MPARAM)wParam
61243a51
DW
4299 ));
4300
4301 if (GetEventHandler()->ProcessEvent(vEvent))
4302 {
4303 return TRUE;
4304 }
4305 }
4306 return FALSE;
0367c1c0 4307} // end of wxWindowOS2::HandleKeyDown
61243a51 4308
0367c1c0 4309bool wxWindowOS2::HandleKeyUp(
a086de98 4310 WXWPARAM wParam
61243a51
DW
4311, WXLPARAM lParam
4312)
86de7616 4313{
1de4baa3 4314 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
61243a51
DW
4315
4316 if (!nId)
4317 {
4318 //
4319 // Normal ASCII char
4320 //
a086de98 4321 nId = (int)wParam;
61243a51
DW
4322 }
4323
4324 if (nId != -1)
4325 {
4326 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
4327 ,nId
4328 ,lParam
a086de98 4329 ,wParam
61243a51
DW
4330 ));
4331
4332 if (GetEventHandler()->ProcessEvent(vEvent))
4333 return TRUE;
4334 }
4335 return FALSE;
0367c1c0 4336} // end of wxWindowOS2::HandleKeyUp
86de7616 4337
cdf1e714
DW
4338// ---------------------------------------------------------------------------
4339// joystick
4340// ---------------------------------------------------------------------------
86de7616 4341
cdf1e714
DW
4342// ---------------------------------------------------------------------------
4343// scrolling
4344// ---------------------------------------------------------------------------
4345
0367c1c0 4346bool wxWindowOS2::OS2OnScroll(
61243a51
DW
4347 int nOrientation
4348, WXWORD wParam
4349, WXWORD wPos
4350, WXHWND hControl
4351)
cdf1e714 4352{
61243a51 4353 if (hControl)
86de7616 4354 {
61243a51
DW
4355 wxWindow* pChild = wxFindWinFromHandle(hControl);
4356
4357 if (pChild )
4358 return pChild->OS2OnScroll( nOrientation
4359 ,wParam
4360 ,wPos
4361 ,hControl
4362 );
cdf1e714 4363 }
86de7616 4364
61243a51
DW
4365 wxScrollWinEvent vEvent;
4366
4367 vEvent.SetPosition(wPos);
4368 vEvent.SetOrientation(nOrientation);
687706f5 4369 vEvent.SetEventObject(this);
61243a51
DW
4370
4371 switch (wParam)
4372 {
4373 case SB_LINEUP:
687706f5 4374 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEUP);
61243a51
DW
4375 break;
4376
4377 case SB_LINEDOWN:
687706f5 4378 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
61243a51
DW
4379 break;
4380
4381 case SB_PAGEUP:
687706f5 4382 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
61243a51
DW
4383 break;
4384
4385 case SB_PAGEDOWN:
687706f5 4386 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
61243a51
DW
4387 break;
4388
4389 case SB_SLIDERPOSITION:
687706f5 4390 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBRELEASE);
61243a51
DW
4391 break;
4392
4393 case SB_SLIDERTRACK:
687706f5 4394 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBTRACK);
61243a51
DW
4395 break;
4396
4397 default:
4398 return FALSE;
4399 }
4400 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 4401} // end of wxWindowOS2::OS2OnScroll
86de7616 4402
d8a3f66c
DW
4403void wxWindowOS2::MoveChildren(
4404 int nDiff
4405)
4406{
5efff147
DW
4407 //
4408 // We want to handle top levels ourself, manually
4409 //
4410 if (!IsTopLevel() && GetAutoLayout())
d8a3f66c 4411 {
f289196b
DW
4412 Layout();
4413 }
4414 else
4415 {
4416 SWP vSwp;
d8a3f66c 4417
2461cfa0
SN
4418 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
4419 node;
4420 node = node->GetNext())
d8a3f66c 4421 {
2461cfa0 4422 wxWindow* pWin = node->GetData();
d8a3f66c 4423
f289196b
DW
4424 ::WinQueryWindowPos( GetHwndOf(pWin)
4425 ,&vSwp
4426 );
3bcf4cce
SN
4427 // Actually, only move children that already are placed on the
4428 // frame, not ones which are still at wxDefaultCoord.
4429 if (vSwp.y == wxDefaultCoord)
4430 continue;
f289196b
DW
4431 if (pWin->IsKindOf(CLASSINFO(wxControl)))
4432 {
4433 wxControl* pCtrl;
4434
4435 //
4436 // Must deal with controls that have margins like ENTRYFIELD. The SWP
4437 // struct of such a control will have and origin offset from its intended
4438 // position by the width of the margins.
4439 //
4440 pCtrl = wxDynamicCast(pWin, wxControl);
4441 vSwp.y -= pCtrl->GetYComp();
4442 vSwp.x -= pCtrl->GetXComp();
4443 }
4444 ::WinSetWindowPos( GetHwndOf(pWin)
4445 ,HWND_TOP
4446 ,vSwp.x
4447 ,vSwp.y - nDiff
4448 ,vSwp.cx
4449 ,vSwp.cy
52df30cf 4450 ,SWP_MOVE
f289196b
DW
4451 );
4452 ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
4453 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
4454 {
4455 wxRadioBox* pRadioBox;
4456
4457 pRadioBox = wxDynamicCast(pWin, wxRadioBox);
4458 pRadioBox->AdjustButtons( (int)vSwp.x
4459 ,(int)vSwp.y - nDiff
4460 ,(int)vSwp.cx
4461 ,(int)vSwp.cy
4462 ,pRadioBox->GetSizeFlags()
4463 );
4464 }
4465 if (pWin->IsKindOf(CLASSINFO(wxSlider)))
4466 {
4467 wxSlider* pSlider;
4468
4469 pSlider = wxDynamicCast(pWin, wxSlider);
4470 pSlider->AdjustSubControls( (int)vSwp.x
4471 ,(int)vSwp.y - nDiff
4472 ,(int)vSwp.cx
4473 ,(int)vSwp.cy
4474 ,(int)pSlider->GetSizeFlags()
4475 );
4476 }
d8a3f66c
DW
4477 }
4478 }
4a46a5df 4479 Refresh();
d8a3f66c
DW
4480} // end of wxWindowOS2::MoveChildren
4481
4482//
4483// Getting the Y position for a window, like a control, is a real
4484// pain. There are three sitatuions we must deal with in determining
77ffb593 4485// the OS2 to wxWidgets Y coordinate.
d8a3f66c
DW
4486//
4487// 1) The controls are created in a dialog.
4488// This is the easiest since a dialog is created with its original
4489// size so the standard: Y = ParentHeight - (Y + ControlHeight);
4490//
4491// 2) The controls are direct children of a frame
4492// In this instance the controls are actually children of the Frame's
4493// client. During creation the frame's client resizes several times
4494// during creation of the status bar and toolbars. The CFrame class
4495// will take care of this using its AlterChildPos proc.
4496//
4497// 3) The controls are children of a panel, which in turn is a child of
4498// a frame.
859e65de
DW
4499// The panel may be one of many, in which case the same treatment
4500// as 1 applies. It may be the only child, though.
d8a3f66c
DW
4501// This is the nastiest case. A panel is created as the only child of
4502// the frame and as such, when a frame has only one child, the child is
4503// expanded to fit the entire client area of the frame. Because the
4504// controls are created BEFORE this occurs their positions are totally
4505// whacked and any call to WinQueryWindowPos will return invalid
4506// coordinates. So for this situation we have to compare the size of
4507// the panel at control creation time with that of the frame client. If
4508// they are the same we can use the standard Y position equation. If
4509// not, then we must use the Frame Client's dimensions to position them
4510// as that will be the eventual size of the panel after the frame resizes
4511// it!
4512//
4513int wxWindowOS2::GetOS2ParentHeight(
4514 wxWindowOS2* pParent
4515)
4516{
d8a3f66c
DW
4517 //
4518 // Case 1
4519 //
4520 if (pParent->IsKindOf(CLASSINFO(wxDialog)))
e37db699 4521 return(pParent->GetClientSize().y);
d8a3f66c
DW
4522
4523 //
4524 // Case 2 -- if we are one of the separately built standard Frame
4525 // children, like a statusbar, menubar, or toolbar we want to
4526 // use the frame, itself, for positioning. Otherwise we are
4527 // child window and want to use the Frame's client.
4528 //
4529 else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
4530 {
4531 if (IsKindOf(CLASSINFO(wxStatusBar)) ||
4532 IsKindOf(CLASSINFO(wxMenuBar)) ||
4533 IsKindOf(CLASSINFO(wxToolBar))
4534 )
2590f154
DW
4535 {
4536 if (IsKindOf(CLASSINFO(wxToolBar)))
4537 {
4538 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
4539
4540 if (pFrame->GetToolBar() == this)
4541 return(pParent->GetSize().y);
4542 else
4543 return(pParent->GetClientSize().y);
4544 }
4545 else
4546 return(pParent->GetSize().y);
4547 }
d8a3f66c
DW
4548 else
4549 return(pParent->GetClientSize().y);
4550 }
d8a3f66c 4551 //
4a46a5df
DW
4552 // Case -- this is for any window that is the sole child of a Frame.
4553 // The grandparent must exist and it must be of type CFrame
4554 // and it's height must be different. Otherwise the standard
4555 // applies.
d8a3f66c
DW
4556 //
4557 else
4558 {
4a46a5df 4559 return(pParent->GetClientSize().y);
d8a3f66c
DW
4560 }
4561 return(0L);
4562} // end of wxWindowOS2::GetOS2ParentHeight
4563
45e0dc94
DW
4564//
4565// OS/2 needs a lot extra manipulation to deal with layouts
4566// for canvas windows, particularly scrolled ones.
4567//
06519806
DW
4568wxWindowCreationHook::wxWindowCreationHook(
4569 wxWindow* pWinBeingCreated
4570)
4571{
4572 gpWinBeingCreated = pWinBeingCreated;
4573} // end of wxWindowCreationHook::wxWindowCreationHook
4574
4575wxWindowCreationHook::~wxWindowCreationHook()
4576{
4577 gpWinBeingCreated = NULL;
4578} // end of wxWindowCreationHook::~wxWindowCreationHook
4579
cdf1e714
DW
4580// ===========================================================================
4581// global functions
4582// ===========================================================================
4583
61243a51 4584void wxGetCharSize(
987da0d4
DW
4585 WXHWND hWnd
4586, int* pX
4587, int* pY
19193a2c 4588,wxFont* WXUNUSED(pTheFont)
61243a51 4589)
cdf1e714 4590{
987da0d4
DW
4591 FONTMETRICS vFM;
4592 HPS hPS;
4593 BOOL rc;
4594
4595 hPS =::WinGetPS(hWnd);
4596
4597 rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
4598 if (rc)
4599 {
4600 if (pX)
4601 *pX = vFM.lAveCharWidth;
4602 if (pY)
4603 *pY = vFM.lEmHeight + vFM.lExternalLeading;
4604 }
4605 else
4606 {
4607 if (pX)
4608 *pX = 10;
4609 if (pY)
4610 *pY = 15;
4611 }
4612 ::WinReleasePS(hPS);
61243a51 4613} // end of wxGetCharSize
cdf1e714 4614
61243a51 4615//
cdf1e714
DW
4616// Returns 0 if was a normal ASCII value, not a special key. This indicates that
4617// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
61243a51
DW
4618//
4619int wxCharCodeOS2ToWX(
4620 int nKeySym
4621)
cdf1e714 4622{
61243a51
DW
4623 int nId = 0;
4624
4625 switch (nKeySym)
4626 {
4627 case VK_BACKTAB: nId = WXK_BACK; break;
4628 case VK_TAB: nId = WXK_TAB; break;
4629 case VK_CLEAR: nId = WXK_CLEAR; break;
4630 case VK_ENTER: nId = WXK_RETURN; break;
4631 case VK_SHIFT: nId = WXK_SHIFT; break;
4632 case VK_CTRL: nId = WXK_CONTROL; break;
4633 case VK_PAUSE: nId = WXK_PAUSE; break;
4634 case VK_SPACE: nId = WXK_SPACE; break;
4635 case VK_ESC: nId = WXK_ESCAPE; break;
4636 case VK_END: nId = WXK_END; break;
4637 case VK_HOME : nId = WXK_HOME; break;
4638 case VK_LEFT : nId = WXK_LEFT; break;
4639 case VK_UP: nId = WXK_UP; break;
4640 case VK_RIGHT: nId = WXK_RIGHT; break;
4641 case VK_DOWN : nId = WXK_DOWN; break;
4642 case VK_PRINTSCRN: nId = WXK_PRINT; break;
4643 case VK_INSERT: nId = WXK_INSERT; break;
4644 case VK_DELETE: nId = WXK_DELETE; break;
a086de98 4645 case VK_CAPSLOCK: nId = WXK_CAPITAL; break;
61243a51
DW
4646 case VK_F1: nId = WXK_F1; break;
4647 case VK_F2: nId = WXK_F2; break;
4648 case VK_F3: nId = WXK_F3; break;
4649 case VK_F4: nId = WXK_F4; break;
4650 case VK_F5: nId = WXK_F5; break;
4651 case VK_F6: nId = WXK_F6; break;
4652 case VK_F7: nId = WXK_F7; break;
4653 case VK_F8: nId = WXK_F8; break;
4654 case VK_F9: nId = WXK_F9; break;
4655 case VK_F10: nId = WXK_F10; break;
4656 case VK_F11: nId = WXK_F11; break;
4657 case VK_F12: nId = WXK_F12; break;
4658 case VK_F13: nId = WXK_F13; break;
4659 case VK_F14: nId = WXK_F14; break;
4660 case VK_F15: nId = WXK_F15; break;
4661 case VK_F16: nId = WXK_F16; break;
4662 case VK_F17: nId = WXK_F17; break;
4663 case VK_F18: nId = WXK_F18; break;
4664 case VK_F19: nId = WXK_F19; break;
4665 case VK_F20: nId = WXK_F20; break;
4666 case VK_F21: nId = WXK_F21; break;
4667 case VK_F22: nId = WXK_F22; break;
4668 case VK_F23: nId = WXK_F23; break;
4669 case VK_F24: nId = WXK_F24; break;
a086de98
DW
4670 case VK_OEM_1: nId = ';'; break;
4671 case VK_OEM_PLUS: nId = '+'; break;
4672 case VK_OEM_COMMA: nId = ','; break;
4673 case VK_OEM_MINUS: nId = '-'; break;
4674 case VK_OEM_PERIOD: nId = '.'; break;
4675 case VK_OEM_2: nId = '/'; break;
4676 case VK_OEM_3: nId = '~'; break;
4677 case VK_OEM_4: nId = '['; break;
4678 case VK_OEM_5: nId = '\\'; break;
4679 case VK_OEM_6: nId = ']'; break;
4680 case VK_OEM_7: nId = '\''; break;
61243a51
DW
4681 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
4682 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
4683 default:
86de7616 4684 {
cdf1e714 4685 return 0;
86de7616
DW
4686 }
4687 }
61243a51
DW
4688 return nId;
4689} // end of wxCharCodeOS2ToWX
86de7616 4690
61243a51
DW
4691int wxCharCodeWXToOS2(
4692 int nId
4693, bool* bIsVirtual
4694)
86de7616 4695{
61243a51
DW
4696 int nKeySym = 0;
4697
4698 *bIsVirtual = TRUE;
4699 switch (nId)
4700 {
4701 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
4702 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
4703 case WXK_CONTROL: nKeySym = VK_CTRL; break;
4704 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
4705 case WXK_END: nKeySym = VK_END; break;
4706 case WXK_HOME : nKeySym = VK_HOME; break;
4707 case WXK_LEFT : nKeySym = VK_LEFT; break;
4708 case WXK_UP: nKeySym = VK_UP; break;
4709 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
4710 case WXK_DOWN : nKeySym = VK_DOWN; break;
4711 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
4712 case WXK_INSERT: nKeySym = VK_INSERT; break;
4713 case WXK_DELETE: nKeySym = VK_DELETE; break;
4714 case WXK_F1: nKeySym = VK_F1; break;
4715 case WXK_F2: nKeySym = VK_F2; break;
4716 case WXK_F3: nKeySym = VK_F3; break;
4717 case WXK_F4: nKeySym = VK_F4; break;
4718 case WXK_F5: nKeySym = VK_F5; break;
4719 case WXK_F6: nKeySym = VK_F6; break;
4720 case WXK_F7: nKeySym = VK_F7; break;
4721 case WXK_F8: nKeySym = VK_F8; break;
4722 case WXK_F9: nKeySym = VK_F9; break;
4723 case WXK_F10: nKeySym = VK_F10; break;
4724 case WXK_F11: nKeySym = VK_F11; break;
4725 case WXK_F12: nKeySym = VK_F12; break;
4726 case WXK_F13: nKeySym = VK_F13; break;
4727 case WXK_F14: nKeySym = VK_F14; break;
4728 case WXK_F15: nKeySym = VK_F15; break;
4729 case WXK_F16: nKeySym = VK_F16; break;
4730 case WXK_F17: nKeySym = VK_F17; break;
4731 case WXK_F18: nKeySym = VK_F18; break;
4732 case WXK_F19: nKeySym = VK_F19; break;
4733 case WXK_F20: nKeySym = VK_F20; break;
4734 case WXK_F21: nKeySym = VK_F21; break;
4735 case WXK_F22: nKeySym = VK_F22; break;
4736 case WXK_F23: nKeySym = VK_F23; break;
4737 case WXK_F24: nKeySym = VK_F24; break;
4738 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
4739 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
4740 default:
cdf1e714 4741 {
61243a51
DW
4742 *bIsVirtual = FALSE;
4743 nKeySym = nId;
cdf1e714
DW
4744 break;
4745 }
86de7616 4746 }
61243a51
DW
4747 return nKeySym;
4748} // end of wxCharCodeWXToOS2
86de7616 4749
61243a51 4750wxWindow* wxGetActiveWindow()
cdf1e714 4751{
61243a51 4752 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
86de7616 4753
61243a51
DW
4754 if (hWnd != 0)
4755 {
4756 return wxFindWinFromHandle((WXHWND)hWnd);
4757 }
4758 return NULL;
4759} // end of wxGetActiveWindow
cdf1e714
DW
4760
4761#ifdef __WXDEBUG__
61243a51
DW
4762const char* wxGetMessageName(
4763 int nMessage)
cdf1e714 4764{
61243a51 4765 switch (nMessage)
86de7616 4766 {
cdf1e714
DW
4767 case 0x0000: return "WM_NULL";
4768 case 0x0001: return "WM_CREATE";
4769 case 0x0002: return "WM_DESTROY";
61243a51
DW
4770 case 0x0004: return "WM_ENABLE";
4771 case 0x0005: return "WM_SHOW";
4772 case 0x0006: return "WM_MOVE";
4773 case 0x0007: return "WM_SIZE";
4774 case 0x0008: return "WM_ADJUSTWINDOWPOS";
4775 case 0x0009: return "WM_CALCVALIDRECTS";
4776 case 0x000A: return "WM_SETWINDOWPARAMS";
4777 case 0x000B: return "WM_QUERYWINDOWPARAMS";
4778 case 0x000C: return "WM_HITTEST";
4779 case 0x000D: return "WM_ACTIVATE";
4780 case 0x000F: return "WM_SETFOCUS";
4781 case 0x0010: return "WM_SETSELECTION";
4782 case 0x0011: return "WM_PPAINT";
4783 case 0x0012: return "WM_PSETFOCUS";
4784 case 0x0013: return "WM_PSYSCOLORCHANGE";
4785 case 0x0014: return "WM_PSIZE";
4786 case 0x0015: return "WM_PACTIVATE";
4787 case 0x0016: return "WM_PCONTROL";
4788 case 0x0020: return "WM_COMMAND";
4789 case 0x0021: return "WM_SYSCOMMAND";
4790 case 0x0022: return "WM_HELP";
4791 case 0x0023: return "WM_PAINT";
4792 case 0x0024: return "WM_TIMER";
4793 case 0x0025: return "WM_SEM1";
4794 case 0x0026: return "WM_SEM2";
4795 case 0x0027: return "WM_SEM3";
4796 case 0x0028: return "WM_SEM4";
4797 case 0x0029: return "WM_CLOSE";
4798 case 0x002A: return "WM_QUIT";
4799 case 0x002B: return "WM_SYSCOLORCHANGE";
4800 case 0x002D: return "WM_SYSVALUECHANGE";
4801 case 0x002E: return "WM_APPTERMINATENOTIFY";
4802 case 0x002F: return "WM_PRESPARAMCHANGED";
4803 // Control notification messages
4804 case 0x0030: return "WM_CONTROL";
4805 case 0x0031: return "WM_VSCROLL";
4806 case 0x0032: return "WM_HSCROLL";
4807 case 0x0033: return "WM_INITMENU";
4808 case 0x0034: return "WM_MENUSELECT";
4809 case 0x0035: return "WM_MENUSEND";
4810 case 0x0036: return "WM_DRAWITEM";
4811 case 0x0037: return "WM_MEASUREITEM";
4812 case 0x0038: return "WM_CONTROLPOINTER";
4813 case 0x003A: return "WM_QUERYDLGCODE";
4814 case 0x003B: return "WM_INITDLG";
4815 case 0x003C: return "WM_SUBSTITUTESTRING";
4816 case 0x003D: return "WM_MATCHMNEMONIC";
4817 case 0x003E: return "WM_SAVEAPPLICATION";
4818 case 0x0129: return "WM_CTLCOLORCHANGE";
4819 case 0x0130: return "WM_QUERYCTLTYPE";
4820 // Frame messages
4821 case 0x0040: return "WM_FLASHWINDOW";
4822 case 0x0041: return "WM_FORMATFRAME";
4823 case 0x0042: return "WM_UPDATEFRAME";
4824 case 0x0043: return "WM_FOCUSCHANGE";
4825 case 0x0044: return "WM_SETBORDERSIZE";
4826 case 0x0045: return "WM_TRACKFRAME";
4827 case 0x0046: return "WM_MINMAXFRAME";
4828 case 0x0047: return "WM_SETICON";
4829 case 0x0048: return "WM_QUERYICON";
4830 case 0x0049: return "WM_SETACCELTABLE";
4831 case 0x004A: return "WM_QUERYACCELTABLE";
4832 case 0x004B: return "WM_TRANSLATEACCEL";
4833 case 0x004C: return "WM_QUERYTRACKINFO";
4834 case 0x004D: return "WM_QUERYBORDERSIZE";
4835 case 0x004E: return "WM_NEXTMENU";
4836 case 0x004F: return "WM_ERASEBACKGROUND";
4837 case 0x0050: return "WM_QUERYFRAMEINFO";
4838 case 0x0051: return "WM_QUERYFOCUSCHAIN";
4839 case 0x0052: return "WM_OWNERPOSCHANGE";
4840 case 0x0053: return "WM_CACLFRAMERECT";
4841 case 0x0055: return "WM_WINDOWPOSCHANGED";
4842 case 0x0056: return "WM_ADJUSTFRAMEPOS";
4843 case 0x0059: return "WM_QUERYFRAMECTLCOUNT";
4844 case 0x005B: return "WM_QUERYHELPINFO";
4845 case 0x005C: return "WM_SETHELPINFO";
4846 case 0x005D: return "WM_ERROR";
4847 case 0x005E: return "WM_REALIZEPALETTE";
4848 // Clipboard messages
4849 case 0x0060: return "WM_RENDERFMT";
4850 case 0x0061: return "WM_RENDERALLFMTS";
4851 case 0x0062: return "WM_DESTROYCLIPBOARD";
4852 case 0x0063: return "WM_PAINTCLIPBOARD";
4853 case 0x0064: return "WM_SIZECLIPBOARD";
4854 case 0x0065: return "WM_HSCROLLCLIPBOARD";
4855 case 0x0066: return "WM_VSCROLLCLIPBOARD";
4856 case 0x0067: return "WM_DRAWCLIPBOARD";
4857 // mouse messages
4858 case 0x0070: return "WM_MOUSEMOVE";
4859 case 0x0071: return "WM_BUTTON1DOWN";
4860 case 0x0072: return "WM_BUTTON1UP";
4861 case 0x0073: return "WM_BUTTON1DBLCLK";
4862 case 0x0074: return "WM_BUTTON2DOWN";
4863 case 0x0075: return "WM_BUTTON2UP";
4864 case 0x0076: return "WM_BUTTON2DBLCLK";
4865 case 0x0077: return "WM_BUTTON3DOWN";
4866 case 0x0078: return "WM_BUTTON3UP";
4867 case 0x0079: return "WM_BUTTON3DBLCLK";
4868 case 0x007D: return "WM_MOUSEMAP";
4869 case 0x007E: return "WM_VRNDISABLED";
4870 case 0x007F: return "WM_VRNENABLED";
4871 case 0x0410: return "WM_CHORD";
4872 case 0x0411: return "WM_BUTTON1MOTIONSTART";
4873 case 0x0412: return "WM_BUTTON1MOTIONEND";
4874 case 0x0413: return "WM_BUTTON1CLICK";
4875 case 0x0414: return "WM_BUTTON2MOTIONSTART";
4876 case 0x0415: return "WM_BUTTON2MOTIONEND";
4877 case 0x0416: return "WM_BUTTON2CLICK";
4878 case 0x0417: return "WM_BUTTON3MOTIONSTART";
4879 case 0x0418: return "WM_BUTTON3MOTIONEND";
4880 case 0x0419: return "WM_BUTTON3CLICK";
4881 case 0x0420: return "WM_BEGINDRAG";
4882 case 0x0421: return "WM_ENDDRAG";
4883 case 0x0422: return "WM_SINGLESELECT";
4884 case 0x0423: return "WM_OPEN";
4885 case 0x0424: return "WM_CONTEXTMENU";
4886 case 0x0425: return "WM_CONTEXTHELP";
4887 case 0x0426: return "WM_TEXTEDIT";
4888 case 0x0427: return "WM_BEGINSELECT";
4889 case 0x0228: return "WM_ENDSELECT";
4890 case 0x0429: return "WM_PICKUP";
4891 case 0x04C0: return "WM_PENFIRST";
4892 case 0x04FF: return "WM_PENLAST";
4893 case 0x0500: return "WM_MMPMFIRST";
4894 case 0x05FF: return "WM_MMPMLAST";
4895 case 0x0600: return "WM_STDDLGFIRST";
4896 case 0x06FF: return "WM_STDDLGLAST";
4897 case 0x0BD0: return "WM_BIDI_FIRST";
4898 case 0x0BFF: return "WM_BIDI_LAST";
4899 // keyboard input
4900 case 0x007A: return "WM_CHAR";
4901 case 0x007B: return "WM_VIOCHAR";
4902 // DDE messages
4903 case 0x00A0: return "WM_DDE_INITIATE";
4904 case 0x00A1: return "WM_DDE_REQUEST";
4905 case 0x00A2: return "WM_DDE_ACK";
4906 case 0x00A3: return "WM_DDE_DATA";
4907 case 0x00A4: return "WM_DDE_ADVISE";
4908 case 0x00A5: return "WM_DDE_UNADVISE";
4909 case 0x00A6: return "WM_DDE_POKE";
4910 case 0x00A7: return "WM_DDE_EXECUTE";
4911 case 0x00A8: return "WM_DDE_TERMINATE";
4912 case 0x00A9: return "WM_DDE_INITIATEACK";
4913 case 0x00AF: return "WM_DDE_LAST";
4914 // Buttons
4915 case 0x0120: return "BM_CLICK";
4916 case 0x0121: return "BM_QUERYCHECKINDEX";
4917 case 0x0122: return "BM_QUERYHILITE";
4918 case 0x0123: return "BM_SETHILITE";
4919 case 0x0124: return "BM_QUERYCHECK";
4920 case 0x0125: return "BM_SETCHECK";
4921 case 0x0126: return "BM_SETDEFAULT";
4922 case 0x0128: return "BM_AUTOSIZE";
4923 // Combo boxes
4924 case 0x029A: return "CBID_LIST";
4925 case 0x029B: return "CBID_EDIT";
4926 case 0x0170: return "CBM_SHOWLIST";
4927 case 0x0171: return "CBM_HILITE";
4928 case 0x0172: return "CBM_ISLISTSHOWING";
4929 // Edit fields
4930 case 0x0140: return "EM_QUERYCHANGED";
4931 case 0x0141: return "EM_QUERYSEL";
4932 case 0x0142: return "EM_SETSEL";
4933 case 0x0143: return "EM_SETTEXTLIMIT";
4934 case 0x0144: return "EM_CUT";
4935 case 0x0145: return "EM_COPY";
4936 case 0x0146: return "EM_CLEAR";
4937 case 0x0147: return "EM_PASTE";
4938 case 0x0148: return "EM_QUERYFIRSTCHAR";
4939 case 0x0149: return "EM_SETFIRSTCHAR";
4940 case 0x014A: return "EM_QUERYREADONLY";
4941 case 0x014B: return "EM_SETREADONLY";
4942 case 0x014C: return "EM_SETINSERTMODE";
4943 // Listboxes
4944 case 0x0160: return "LM_QUERYITEMCOUNT";
4945 case 0x0161: return "LM_INSERTITEM";
4946 case 0x0162: return "LM_SETOPENINDEX";
4947 case 0x0163: return "LM_DELETEITEM";
4948 case 0x0164: return "LM_SELECTITEM";
4949 case 0x0165: return "LM_QUERYSELECTION";
4950 case 0x0166: return "LM_SETITEMTEXT";
4951 case 0x0167: return "LM_QUERYITEMTEXTLENGTH";
4952 case 0x0168: return "LM_QUERYITEMTEXT";
4953 case 0x0169: return "LM_SETITEMHANDLE";
4954 case 0x016A: return "LM_QUERYITEMHANDLE";
4955 case 0x016B: return "LM_SEARCHSTRING";
4956 case 0x016C: return "LM_SETITEMHEIGHT";
4957 case 0x016D: return "LM_QUERYTOPINDEX";
4958 case 0x016E: return "LM_DELETEALL";
4959 case 0x016F: return "LM_INSERTMULITEMS";
4960 case 0x0660: return "LM_SETITEMWIDTH";
4961 // Menus
4962 case 0x0180: return "MM_INSERTITEM";
4963 case 0x0181: return "MM_DELETEITEM";
4964 case 0x0182: return "MM_QUERYITEM";
4965 case 0x0183: return "MM_SETITEM";
4966 case 0x0184: return "MM_QUERYITEMCOUNT";
4967 case 0x0185: return "MM_STARTMENUMODE";
4968 case 0x0186: return "MM_ENDMENUMODE";
4969 case 0x0188: return "MM_REMOVEITEM";
4970 case 0x0189: return "MM_SELECTITEM";
4971 case 0x018A: return "MM_QUERYSELITEMID";
4972 case 0x018B: return "MM_QUERYITEMTEXT";
4973 case 0x018C: return "MM_QUERYITEMTEXTLENGTH";
4974 case 0x018D: return "MM_SETITEMHANDLE";
4975 case 0x018E: return "MM_SETITEMTEXT";
4976 case 0x018F: return "MM_ITEMPOSITIONFROMID";
4977 case 0x0190: return "MM_ITEMIDFROMPOSITION";
4978 case 0x0191: return "MM_QUERYITEMATTR";
4979 case 0x0192: return "MM_SETITEMATTR";
4980 case 0x0193: return "MM_ISITEMVALID";
4981 case 0x0194: return "MM_QUERYITEMRECT";
4982 case 0x0431: return "MM_QUERYDEFAULTITEMID";
4983 case 0x0432: return "MM_SETDEFAULTITEMID";
4984 // Scrollbars
4985 case 0x01A0: return "SBM_SETSCROLLBAR";
4986 case 0x01A1: return "SBM_SETPOS";
4987 case 0x01A2: return "SBM_QUERYPOS";
4988 case 0x01A3: return "SBM_QUERYRANGE";
4989 case 0x01A6: return "SBM_SETTHUMBSIZE";
4990
4991 // Help messages
4992 case 0x0F00: return "WM_HELPBASE";
4993 case 0x0FFF: return "WM_HELPTOP";
4994 // Beginning of user defined messages
4995 case 0x1000: return "WM_USER";
4996
77ffb593 4997 // wxWidgets user defined types
cdf1e714
DW
4998
4999 // listview
61243a51 5000 // case 0x1000 + 0: return "LVM_GETBKCOLOR";
cdf1e714
DW
5001 case 0x1000 + 1: return "LVM_SETBKCOLOR";
5002 case 0x1000 + 2: return "LVM_GETIMAGELIST";
5003 case 0x1000 + 3: return "LVM_SETIMAGELIST";
5004 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
5005 case 0x1000 + 5: return "LVM_GETITEMA";
5006 case 0x1000 + 75: return "LVM_GETITEMW";
5007 case 0x1000 + 6: return "LVM_SETITEMA";
5008 case 0x1000 + 76: return "LVM_SETITEMW";
5009 case 0x1000 + 7: return "LVM_INSERTITEMA";
5010 case 0x1000 + 77: return "LVM_INSERTITEMW";
5011 case 0x1000 + 8: return "LVM_DELETEITEM";
5012 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
5013 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
5014 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
5015 case 0x1000 + 12: return "LVM_GETNEXTITEM";
5016 case 0x1000 + 13: return "LVM_FINDITEMA";
5017 case 0x1000 + 83: return "LVM_FINDITEMW";
5018 case 0x1000 + 14: return "LVM_GETITEMRECT";
5019 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
5020 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
5021 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
5022 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
5023 case 0x1000 + 18: return "LVM_HITTEST";
5024 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
5025 case 0x1000 + 20: return "LVM_SCROLL";
5026 case 0x1000 + 21: return "LVM_REDRAWITEMS";
5027 case 0x1000 + 22: return "LVM_ARRANGE";
5028 case 0x1000 + 23: return "LVM_EDITLABELA";
5029 case 0x1000 + 118: return "LVM_EDITLABELW";
5030 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
5031 case 0x1000 + 25: return "LVM_GETCOLUMNA";
5032 case 0x1000 + 95: return "LVM_GETCOLUMNW";
5033 case 0x1000 + 26: return "LVM_SETCOLUMNA";
5034 case 0x1000 + 96: return "LVM_SETCOLUMNW";
5035 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
5036 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
5037 case 0x1000 + 28: return "LVM_DELETECOLUMN";
5038 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
5039 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
5040 case 0x1000 + 31: return "LVM_GETHEADER";
5041 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
5042 case 0x1000 + 34: return "LVM_GETVIEWRECT";
5043 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
5044 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
5045 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
5046 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
5047 case 0x1000 + 39: return "LVM_GETTOPINDEX";
5048 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
5049 case 0x1000 + 41: return "LVM_GETORIGIN";
5050 case 0x1000 + 42: return "LVM_UPDATE";
5051 case 0x1000 + 43: return "LVM_SETITEMSTATE";
5052 case 0x1000 + 44: return "LVM_GETITEMSTATE";
5053 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
5054 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
5055 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
5056 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
5057 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
5058 case 0x1000 + 48: return "LVM_SORTITEMS";
5059 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
5060 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
5061 case 0x1000 + 51: return "LVM_GETITEMSPACING";
5062 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
5063 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
5064 case 0x1000 + 53: return "LVM_SETICONSPACING";
5065 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
5066 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
5067 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
5068 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
5069 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
5070 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
5071 case 0x1000 + 60: return "LVM_SETHOTITEM";
5072 case 0x1000 + 61: return "LVM_GETHOTITEM";
5073 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
5074 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
5075 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
5076 case 0x1000 + 65: return "LVM_SETWORKAREA";
5077
5078 // tree view
5079 case 0x1100 + 0: return "TVM_INSERTITEMA";
5080 case 0x1100 + 50: return "TVM_INSERTITEMW";
5081 case 0x1100 + 1: return "TVM_DELETEITEM";
5082 case 0x1100 + 2: return "TVM_EXPAND";
5083 case 0x1100 + 4: return "TVM_GETITEMRECT";
5084 case 0x1100 + 5: return "TVM_GETCOUNT";
5085 case 0x1100 + 6: return "TVM_GETINDENT";
5086 case 0x1100 + 7: return "TVM_SETINDENT";
5087 case 0x1100 + 8: return "TVM_GETIMAGELIST";
5088 case 0x1100 + 9: return "TVM_SETIMAGELIST";
5089 case 0x1100 + 10: return "TVM_GETNEXTITEM";
5090 case 0x1100 + 11: return "TVM_SELECTITEM";
5091 case 0x1100 + 12: return "TVM_GETITEMA";
5092 case 0x1100 + 62: return "TVM_GETITEMW";
5093 case 0x1100 + 13: return "TVM_SETITEMA";
5094 case 0x1100 + 63: return "TVM_SETITEMW";
5095 case 0x1100 + 14: return "TVM_EDITLABELA";
5096 case 0x1100 + 65: return "TVM_EDITLABELW";
5097 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
5098 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
5099 case 0x1100 + 17: return "TVM_HITTEST";
5100 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
5101 case 0x1100 + 19: return "TVM_SORTCHILDREN";
5102 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
5103 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
5104 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
5105 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
5106 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
5107 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
5108 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
5109
5110 // header
5111 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
5112 case 0x1200 + 1: return "HDM_INSERTITEMA";
5113 case 0x1200 + 10: return "HDM_INSERTITEMW";
5114 case 0x1200 + 2: return "HDM_DELETEITEM";
5115 case 0x1200 + 3: return "HDM_GETITEMA";
5116 case 0x1200 + 11: return "HDM_GETITEMW";
5117 case 0x1200 + 4: return "HDM_SETITEMA";
5118 case 0x1200 + 12: return "HDM_SETITEMW";
5119 case 0x1200 + 5: return "HDM_LAYOUT";
5120 case 0x1200 + 6: return "HDM_HITTEST";
5121 case 0x1200 + 7: return "HDM_GETITEMRECT";
5122 case 0x1200 + 8: return "HDM_SETIMAGELIST";
5123 case 0x1200 + 9: return "HDM_GETIMAGELIST";
5124 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
5125 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
5126 case 0x1200 + 17: return "HDM_GETORDERARRAY";
5127 case 0x1200 + 18: return "HDM_SETORDERARRAY";
5128 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
5129
5130 // tab control
5131 case 0x1300 + 2: return "TCM_GETIMAGELIST";
5132 case 0x1300 + 3: return "TCM_SETIMAGELIST";
5133 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
5134 case 0x1300 + 5: return "TCM_GETITEMA";
5135 case 0x1300 + 60: return "TCM_GETITEMW";
5136 case 0x1300 + 6: return "TCM_SETITEMA";
5137 case 0x1300 + 61: return "TCM_SETITEMW";
5138 case 0x1300 + 7: return "TCM_INSERTITEMA";
5139 case 0x1300 + 62: return "TCM_INSERTITEMW";
5140 case 0x1300 + 8: return "TCM_DELETEITEM";
5141 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
5142 case 0x1300 + 10: return "TCM_GETITEMRECT";
5143 case 0x1300 + 11: return "TCM_GETCURSEL";
5144 case 0x1300 + 12: return "TCM_SETCURSEL";
5145 case 0x1300 + 13: return "TCM_HITTEST";
5146 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
5147 case 0x1300 + 40: return "TCM_ADJUSTRECT";
5148 case 0x1300 + 41: return "TCM_SETITEMSIZE";
5149 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
5150 case 0x1300 + 43: return "TCM_SETPADDING";
5151 case 0x1300 + 44: return "TCM_GETROWCOUNT";
5152 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
5153 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
5154 case 0x1300 + 47: return "TCM_GETCURFOCUS";
5155 case 0x1300 + 48: return "TCM_SETCURFOCUS";
5156 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
5157 case 0x1300 + 50: return "TCM_DESELECTALL";
5158
5159 // toolbar
61243a51
DW
5160 case WM_USER+1000+1: return "TB_ENABLEBUTTON";
5161 case WM_USER+1000+2: return "TB_CHECKBUTTON";
5162 case WM_USER+1000+3: return "TB_PRESSBUTTON";
5163 case WM_USER+1000+4: return "TB_HIDEBUTTON";
5164 case WM_USER+1000+5: return "TB_INDETERMINATE";
5165 case WM_USER+1000+9: return "TB_ISBUTTONENABLED";
5166 case WM_USER+1000+10: return "TB_ISBUTTONCHECKED";
5167 case WM_USER+1000+11: return "TB_ISBUTTONPRESSED";
5168 case WM_USER+1000+12: return "TB_ISBUTTONHIDDEN";
5169 case WM_USER+1000+13: return "TB_ISBUTTONINDETERMINATE";
5170 case WM_USER+1000+17: return "TB_SETSTATE";
5171 case WM_USER+1000+18: return "TB_GETSTATE";
5172 case WM_USER+1000+19: return "TB_ADDBITMAP";
5173 case WM_USER+1000+20: return "TB_ADDBUTTONS";
5174 case WM_USER+1000+21: return "TB_INSERTBUTTON";
5175 case WM_USER+1000+22: return "TB_DELETEBUTTON";
5176 case WM_USER+1000+23: return "TB_GETBUTTON";
5177 case WM_USER+1000+24: return "TB_BUTTONCOUNT";
5178 case WM_USER+1000+25: return "TB_COMMANDTOINDEX";
5179 case WM_USER+1000+26: return "TB_SAVERESTOREA";
5180 case WM_USER+1000+76: return "TB_SAVERESTOREW";
5181 case WM_USER+1000+27: return "TB_CUSTOMIZE";
5182 case WM_USER+1000+28: return "TB_ADDSTRINGA";
5183 case WM_USER+1000+77: return "TB_ADDSTRINGW";
5184 case WM_USER+1000+29: return "TB_GETITEMRECT";
5185 case WM_USER+1000+30: return "TB_BUTTONSTRUCTSIZE";
5186 case WM_USER+1000+31: return "TB_SETBUTTONSIZE";
5187 case WM_USER+1000+32: return "TB_SETBITMAPSIZE";
5188 case WM_USER+1000+33: return "TB_AUTOSIZE";
5189 case WM_USER+1000+35: return "TB_GETTOOLTIPS";
5190 case WM_USER+1000+36: return "TB_SETTOOLTIPS";
5191 case WM_USER+1000+37: return "TB_SETPARENT";
5192 case WM_USER+1000+39: return "TB_SETROWS";
5193 case WM_USER+1000+40: return "TB_GETROWS";
5194 case WM_USER+1000+42: return "TB_SETCMDID";
5195 case WM_USER+1000+43: return "TB_CHANGEBITMAP";
5196 case WM_USER+1000+44: return "TB_GETBITMAP";
5197 case WM_USER+1000+45: return "TB_GETBUTTONTEXTA";
5198 case WM_USER+1000+75: return "TB_GETBUTTONTEXTW";
5199 case WM_USER+1000+46: return "TB_REPLACEBITMAP";
5200 case WM_USER+1000+47: return "TB_SETINDENT";
5201 case WM_USER+1000+48: return "TB_SETIMAGELIST";
5202 case WM_USER+1000+49: return "TB_GETIMAGELIST";
5203 case WM_USER+1000+50: return "TB_LOADIMAGES";
5204 case WM_USER+1000+51: return "TB_GETRECT";
5205 case WM_USER+1000+52: return "TB_SETHOTIMAGELIST";
5206 case WM_USER+1000+53: return "TB_GETHOTIMAGELIST";
5207 case WM_USER+1000+54: return "TB_SETDISABLEDIMAGELIST";
5208 case WM_USER+1000+55: return "TB_GETDISABLEDIMAGELIST";
5209 case WM_USER+1000+56: return "TB_SETSTYLE";
5210 case WM_USER+1000+57: return "TB_GETSTYLE";
5211 case WM_USER+1000+58: return "TB_GETBUTTONSIZE";
5212 case WM_USER+1000+59: return "TB_SETBUTTONWIDTH";
5213 case WM_USER+1000+60: return "TB_SETMAXTEXTROWS";
5214 case WM_USER+1000+61: return "TB_GETTEXTROWS";
5215 case WM_USER+1000+41: return "TB_GETBITMAPFLAGS";
cdf1e714
DW
5216
5217 default:
5218 static char s_szBuf[128];
61243a51 5219 sprintf(s_szBuf, "<unknown message = %d>", nMessage);
cdf1e714 5220 return s_szBuf;
86de7616 5221 }
cdf1e714 5222 return NULL;
61243a51 5223} // end of wxGetMessageName
86de7616 5224
11e59d47
DW
5225#endif // __WXDEBUG__
5226
19193a2c
KB
5227// Unused?
5228#if 0
61243a51
DW
5229static void TranslateKbdEventToMouse(
5230 wxWindow* pWin
5231, int* pX
5232, int* pY
5233, ULONG* pFlags
5234)
5235{
5236 //
5237 // Construct the key mask
5238 ULONG& fwKeys = *pFlags;
5239
5240 fwKeys = VK_BUTTON2;
5241 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
5242 fwKeys |= VK_CTRL;
5243 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
5244 fwKeys |= VK_SHIFT;
5245
5246 //
5247 // Simulate right mouse button click
5248 //
5249 POINTL vPoint;
5250
5251 ::WinQueryMsgPos(vHabmain, &vPoint);
5252 *pX = vPoint.x;
5253 *pY = vPoint.y;
5254
5255 pWin->ScreenToClient(pX, pY);
5256} // end of TranslateKbdEventToMouse
19193a2c 5257#endif
61243a51 5258
cd212ee4
DW
5259// Find the wxWindow at the current mouse position, returning the mouse
5260// position.
f44fdfb0 5261wxWindow* wxFindWindowAtPointer(
19193a2c 5262 wxPoint& WXUNUSED(rPt)
f44fdfb0 5263)
cd212ee4
DW
5264{
5265 return wxFindWindowAtPoint(wxGetMousePosition());
5266}
5267
f44fdfb0
DW
5268wxWindow* wxFindWindowAtPoint(
5269 const wxPoint& rPt
5270)
cd212ee4 5271{
f44fdfb0 5272 POINTL vPt2;
cd212ee4 5273
f44fdfb0
DW
5274 vPt2.x = rPt.x;
5275 vPt2.y = rPt.y;
cd212ee4 5276
f44fdfb0
DW
5277 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
5278 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
5279 HWND hWnd = hWndHit;
5280
5281 //
cd212ee4 5282 // Try to find a window with a wxWindow associated with it
f44fdfb0
DW
5283 //
5284 while (!pWin && (hWnd != 0))
cd212ee4 5285 {
f44fdfb0
DW
5286 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
5287 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
cd212ee4 5288 }
f44fdfb0 5289 return pWin;
cd212ee4
DW
5290}
5291
f44fdfb0
DW
5292// Get the current mouse position.
5293wxPoint wxGetMousePosition()
5294{
5295 POINTL vPt;
5296
5297 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
5298 return wxPoint(vPt.x, vPt.y);
5299}
cd212ee4 5300
430974f8
DW
5301wxWindowOS2* FindWindowForMouseEvent(
5302 wxWindow* pWin
5303, short* pnX
5304, short* pnY
5305)
5306{
430974f8
DW
5307 HWND hWnd = GetHwndOf(pWin);
5308 HWND hWndUnderMouse;
b720b24d
DW
5309 POINTL vPoint;
5310 BOOL rcEnabled = FALSE;
5311 BOOL rcVisible = FALSE;
430974f8 5312
b720b24d
DW
5313 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
5314 hWndUnderMouse = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
5315 if (hWndUnderMouse != HWND_DESKTOP)
430974f8 5316 {
b720b24d
DW
5317 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5318
5319 if (pWinUnderMouse)
5320 {
2461cfa0 5321 wxWindowList::compatibility_iterator current = pWinUnderMouse->GetChildren().GetFirst();
b720b24d
DW
5322 wxWindow* pGrandChild = NULL;
5323 RECTL vRect;
5324 POINTL vPoint2;
5325
5326 ::WinMapWindowPoints(HWND_DESKTOP, hWndUnderMouse, &vPoint, 1);
5327 //
5328 // Find a child window mouse might be under
5329 //
2461cfa0 5330 while (current)
b720b24d 5331 {
2461cfa0 5332 wxWindow* pChild = current->GetData();
b720b24d
DW
5333
5334 vPoint2.x = vPoint.x;
5335 vPoint2.y = vPoint.y;
5336 ::WinMapWindowPoints(hWndUnderMouse, pChild->GetHWND(), &vPoint2, 1);
5337 ::WinQueryWindowRect(pChild->GetHWND(), &vRect);
5338 if (::WinPtInRect(vHabmain, &vRect, &vPoint2))
5339 {
5340 if (pChild->IsTopLevel())
5341 {
5342 POINTL vPoint3;
2461cfa0 5343 wxWindowList::compatibility_iterator current2 =pChild->GetChildren().GetFirst();
430974f8 5344
2461cfa0 5345 while (current2)
b720b24d 5346 {
2461cfa0 5347 wxWindow* pGrandChild = current2->GetData();
b720b24d
DW
5348
5349 vPoint3.x = vPoint2.x;
5350 vPoint3.y = vPoint2.y;
5351 ::WinMapWindowPoints( pChild->GetHWND()
5352 ,pGrandChild->GetHWND()
5353 ,&vPoint3
5354 ,1
5355 );
5356 ::WinQueryWindowRect(pGrandChild->GetHWND(), &vRect);
5357 if (::WinPtInRect(vHabmain, &vRect, &vPoint3))
5358 {
5359 hWndUnderMouse = GetHwndOf(pGrandChild);
5360 pWinUnderMouse = pGrandChild;
5361 break;
5362 }
2461cfa0 5363 current2 = current2->GetNext();
b720b24d
DW
5364 }
5365 if (pGrandChild)
5366 break;
5367 }
5368 hWndUnderMouse = GetHwndOf(pChild);
5369 pWinUnderMouse = pChild;
5370 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5371 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5372 if (rcVisible && rcEnabled)
5373 break;
5374 }
2461cfa0 5375 current = current->GetNext();
b720b24d
DW
5376 }
5377 }
430974f8 5378 }
b720b24d
DW
5379 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5380 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5381
430974f8
DW
5382
5383 //
5384 // Check that we have a child window which is susceptible to receive mouse
5385 // events: for this it must be shown and enabled
b720b24d 5386 //
430974f8
DW
5387 if ( hWndUnderMouse &&
5388 hWndUnderMouse != hWnd &&
b720b24d 5389 rcVisible && rcEnabled)
430974f8 5390 {
b720b24d
DW
5391 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5392
430974f8
DW
5393 if (pWinUnderMouse)
5394 {
b720b24d
DW
5395 //
5396 // Translate the mouse coords to the other window coords
5397 //
430974f8
DW
5398 pWin = pWinUnderMouse;
5399 }
5400 }
5401 return pWin;
5402} // end of FindWindowForMouseEvent
5403