]> git.saurik.com Git - wxWidgets.git/blame - src/os2/window.cpp
src/common/wxchar.cpps/wxConvLocal/wxConvLibs/g as otherwise we may fail to convert...
[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{
f38374d0 586 ::WinSetWindowText(GetHwnd(), 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 );
524d72c4 1626 nYDiff += nAdjustHeight;
859e65de
DW
1627 }
1628 MoveChildren(nYDiff);
1629 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1630 }
9e705092 1631 MoveChildren(nHeightDelta);
0367c1c0 1632} // end of wxWindowOS2::DoMoveWindow
cdf1e714 1633
c86c44a0
DW
1634//
1635// Set the size of the window: if the dimensions are positive, just use them,
cdf1e714
DW
1636// but if any of them is equal to -1, it means that we must find the value for
1637// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1638// which case -1 is a valid value for x and y)
1639//
1640// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1641// the width/height to best suit our contents, otherwise we reuse the current
1642// width/height
c86c44a0 1643//
0367c1c0 1644void wxWindowOS2::DoSetSize(
a7ef993c
DW
1645 int nX
1646, int nY
1647, int nWidth
1648, int nHeight
1649, int nSizeFlags
1650)
cdf1e714 1651{
a7ef993c
DW
1652 //
1653 // Get the current size and position...
1654 //
1655 int nCurrentX;
1656 int nCurrentY;
1657 int nCurrentWidth;
1658 int nCurrentHeight;
542875a8 1659 wxSize vSize(-1, -1);
a7ef993c 1660
19193a2c
KB
1661 GetPosition(&nCurrentX, &nCurrentY);
1662 GetSize(&nCurrentWidth, &nCurrentHeight);
c86c44a0 1663
5d44b24e 1664 //
c86c44a0 1665 // ... and don't do anything (avoiding flicker) if it's already ok
5d44b24e
DW
1666 //
1667 //
1668 // Must convert Y coords to test for equality under OS/2
1669 //
1670 int nY2 = nY;
5d44b24e 1671
5d44b24e 1672 if (nX == nCurrentX && nY2 == nCurrentY &&
19193a2c 1673 nWidth == nCurrentWidth && nHeight == nCurrentHeight)
c86c44a0
DW
1674 {
1675 return;
1676 }
1677
a7ef993c
DW
1678 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1679 nX = nCurrentX;
542875a8 1680 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
a7ef993c 1681 nY = nCurrentY;
c86c44a0 1682
19193a2c 1683 AdjustForParentClientOrigin(nX, nY, nSizeFlags);
c86c44a0 1684
a7ef993c 1685 if (nWidth == -1)
c86c44a0 1686 {
a7ef993c 1687 if (nSizeFlags & wxSIZE_AUTO_WIDTH)
c86c44a0 1688 {
a7ef993c
DW
1689 vSize = DoGetBestSize();
1690 nWidth = vSize.x;
c86c44a0
DW
1691 }
1692 else
1693 {
a7ef993c
DW
1694 //
1695 // Just take the current one
1696 //
1697 nWidth = nCurrentWidth;
c86c44a0
DW
1698 }
1699 }
1700
a7ef993c 1701 if (nHeight == -1)
c86c44a0 1702 {
a7ef993c 1703 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
c86c44a0 1704 {
a7ef993c 1705 if (vSize.x == -1)
c86c44a0 1706 {
a7ef993c 1707 vSize = DoGetBestSize();
c86c44a0 1708 }
a7ef993c 1709 nHeight = vSize.y;
c86c44a0
DW
1710 }
1711 else
1712 {
1713 // just take the current one
a7ef993c 1714 nHeight = nCurrentHeight;
c86c44a0
DW
1715 }
1716 }
1717
a7ef993c
DW
1718 DoMoveWindow( nX
1719 ,nY
1720 ,nWidth
1721 ,nHeight
1722 );
0367c1c0 1723} // end of wxWindowOS2::DoSetSize
cdf1e714 1724
0367c1c0 1725void wxWindowOS2::DoSetClientSize(
a7ef993c
DW
1726 int nWidth
1727, int nHeight
1728)
cdf1e714 1729{
8330166c 1730 POINTL vPoint;
b720b24d
DW
1731 int nActualWidth;
1732 int nActualHeight;
1733 wxWindow* pParent = (wxWindow*)GetParent();
1734 HWND hParentWnd = (HWND)0;
c86c44a0 1735
b720b24d
DW
1736 if (pParent)
1737 hParentWnd = (HWND)pParent->GetHWND();
8330166c 1738
b720b24d
DW
1739 if (IsKindOf(CLASSINFO(wxFrame)))
1740 {
1741 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1742 HWND hFrame = pFrame->GetFrame();
1743 RECTL vRect;
1744 RECTL vRect2;
1745 RECTL vRect3;
c86c44a0 1746
b720b24d
DW
1747 ::WinQueryWindowRect(GetHwnd(), &vRect2);
1748 ::WinQueryWindowRect(hFrame, &vRect);
1749 ::WinQueryWindowRect(hParentWnd, &vRect3);
1750 nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
1751 nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
1752
1753 vPoint.x = vRect2.xLeft;
1754 vPoint.y = vRect2.yBottom;
1755 if (pParent)
1756 {
1757 vPoint.x -= vRect3.xLeft;
1758 vPoint.y -= vRect3.yBottom;
1759 }
1760 }
1761 else
8330166c 1762 {
b720b24d
DW
1763 int nX;
1764 int nY;
1765
1766 GetPosition(&nX, &nY);
1767 nActualWidth = nWidth;
1768 nActualHeight = nHeight;
1769
1770 vPoint.x = nX;
1771 vPoint.y = nY;
c86c44a0 1772 }
b720b24d
DW
1773 DoMoveWindow( vPoint.x
1774 ,vPoint.y
1775 ,nActualWidth
1776 ,nActualHeight
1777 );
19193a2c 1778
b720b24d
DW
1779 wxSizeEvent vEvent( wxSize( nWidth
1780 ,nHeight
1781 )
1782 ,m_windowId
1783 );
19193a2c 1784
a7ef993c
DW
1785 vEvent.SetEventObject(this);
1786 GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 1787} // end of wxWindowOS2::DoSetClientSize
cdf1e714 1788
cdf1e714
DW
1789// ---------------------------------------------------------------------------
1790// text metrics
1791// ---------------------------------------------------------------------------
1792
0367c1c0 1793int wxWindowOS2::GetCharHeight() const
cdf1e714 1794{
a7ef993c
DW
1795 HPS hPs;
1796 FONTMETRICS vFontMetrics;
cdf1e714 1797
a7ef993c
DW
1798 hPs = ::WinGetPS(GetHwnd());
1799
542875a8 1800 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1801 {
1802 ::WinReleasePS(hPs);
a7ef993c 1803 return (0);
b7084589 1804 }
a7ef993c 1805 ::WinReleasePS(hPs);
b7084589 1806 return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender);
0367c1c0 1807} // end of wxWindowOS2::GetCharHeight
a7ef993c 1808
0367c1c0 1809int wxWindowOS2::GetCharWidth() const
cdf1e714 1810{
542875a8
DW
1811 HPS hPs;
1812 FONTMETRICS vFontMetrics;
1813
a7ef993c 1814 hPs = ::WinGetPS(GetHwnd());
cdf1e714 1815
542875a8 1816 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1817 {
1818 ::WinReleasePS(hPs);
a7ef993c 1819 return (0);
b7084589 1820 }
a7ef993c 1821 ::WinReleasePS(hPs);
b7084589 1822 return(vFontMetrics.lAveCharWidth);
0367c1c0 1823} // end of wxWindowOS2::GetCharWidth
a7ef993c 1824
0367c1c0 1825void wxWindowOS2::GetTextExtent(
a7ef993c
DW
1826 const wxString& rString
1827, int* pX
1828, int* pY
1829, int* pDescent
1830, int* pExternalLeading
1831, const wxFont* pTheFont
1832) const
cdf1e714 1833{
987da0d4
DW
1834 POINTL avPoint[TXTBOX_COUNT];
1835 POINTL vPtMin;
1836 POINTL vPtMax;
1837 int i;
1838 int l;
1839 FONTMETRICS vFM; // metrics structure
72bfca58 1840 BOOL bRc = FALSE;
987da0d4 1841 char* pStr;
987da0d4 1842 HPS hPS;
19193a2c 1843
a7ef993c 1844
987da0d4 1845 hPS = ::WinGetPS(GetHwnd());
a7ef993c 1846
987da0d4
DW
1847 l = rString.Length();
1848 if (l > 0L)
1849 {
1850 pStr = (PCH)rString.c_str();
a7ef993c 1851
987da0d4
DW
1852 //
1853 // In world coordinates.
1854 //
1855 bRc = ::GpiQueryTextBox( hPS
1856 ,l
1857 ,pStr
1858 ,TXTBOX_COUNT // return maximum information
1859 ,avPoint // array of coordinates points
1860 );
1861 if (bRc)
1862 {
1863 vPtMin.x = avPoint[0].x;
1864 vPtMax.x = avPoint[0].x;
1865 vPtMin.y = avPoint[0].y;
1866 vPtMax.y = avPoint[0].y;
1867 for (i = 1; i < 4; i++)
1868 {
1869 if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
1870 if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
1871 if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
1872 if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
1873 }
1874 bRc = ::GpiQueryFontMetrics( hPS
1875 ,sizeof(FONTMETRICS)
1876 ,&vFM
1877 );
1878 if (!bRc)
1879 {
1880 vPtMin.x = 0;
1881 vPtMin.y = 0;
1882 vPtMax.x = 0;
1883 vPtMax.y = 0;
1884 }
1885 }
1886 else
1887 {
1888 vPtMin.x = 0;
1889 vPtMin.y = 0;
1890 vPtMax.x = 0;
1891 vPtMax.y = 0;
1892 }
1893 }
1894 else
a7ef993c 1895 {
987da0d4
DW
1896 vPtMin.x = 0;
1897 vPtMin.y = 0;
1898 vPtMax.x = 0;
1899 vPtMax.y = 0;
a7ef993c 1900 }
987da0d4
DW
1901 if (pX)
1902 *pX = (vPtMax.x - vPtMin.x + 1);
1903 if (pY)
1904 *pY = (vPtMax.y - vPtMin.y + 1);
1905 if (pDescent)
1906 {
1907 if (bRc)
1908 *pDescent = vFM.lMaxDescender;
1909 else
1910 *pDescent = 0;
1911 }
1912 if (pExternalLeading)
1913 {
1914 if (bRc)
1915 *pExternalLeading = vFM.lExternalLeading;
1916 else
1917 *pExternalLeading = 0;
1918 }
1919 ::WinReleasePS(hPS);
1920} // end of wxWindow::GetTextExtent
cdf1e714 1921
f9efbe3a
DW
1922bool wxWindowOS2::IsMouseInWindow() const
1923{
1924 //
1925 // Get the mouse position
1926 POINTL vPt;
1927
1928 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
1929
1930 //
1931 // Find the window which currently has the cursor and go up the window
1932 // chain until we find this window - or exhaust it
1933 //
1934 HWND hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPt, TRUE);
1935
1936 while (hWnd && (hWnd != GetHwnd()))
1937 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
1938
1939 return hWnd != NULL;
1940} // end of wxWindowOS2::IsMouseInWindow
1941
cdf1e714
DW
1942
1943// ---------------------------------------------------------------------------
1944// popup menu
1945// ---------------------------------------------------------------------------
19193a2c 1946//
19193a2c 1947#if wxUSE_MENUS_NATIVE
0367c1c0 1948bool wxWindowOS2::DoPopupMenu(
61243a51
DW
1949 wxMenu* pMenu
1950, int nX
1951, int nY
1952)
cdf1e714 1953{
239c2e96
DW
1954 HWND hWndOwner = GetHwnd();
1955 HWND hWndParent = GetHwnd();
61243a51 1956 HWND hMenu = GetHmenuOf(pMenu);
239c2e96 1957 bool bIsWaiting = TRUE;
c82be69b
JS
1958 int nHeight;
1959
1960 // Protect against recursion
1961 if (wxCurrentPopupMenu)
1962 return false;
61243a51
DW
1963
1964 pMenu->SetInvokingWindow(this);
1965 pMenu->UpdateUI();
c82be69b 1966
5d826f60 1967 if ( nX == -1 && nY == -1 )
971562cb
VS
1968 {
1969 wxPoint mouse = wxGetMousePosition();
1970 nX = mouse.x; nY = mouse.y;
1971 }
1972 else
1973 {
1974 DoClientToScreen( &nX
1975 ,&nY
1976 );
c82be69b
JS
1977 DoGetSize(0,&nHeight);
1978 nY = nHeight - nY;
971562cb 1979 }
61243a51
DW
1980 wxCurrentPopupMenu = pMenu;
1981
1982 ::WinPopupMenu( hWndParent
239c2e96 1983 ,hWndOwner
61243a51
DW
1984 ,hMenu
1985 ,nX
1986 ,nY
1987 ,0L
bdfd8d77 1988 ,PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 | PU_KEYBOARD
61243a51 1989 );
bdfd8d77 1990
239c2e96
DW
1991 while(bIsWaiting)
1992 {
bdfd8d77 1993 QMSG vMsg;
239c2e96 1994
c82be69b
JS
1995 ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
1996 if (vMsg.msg == WM_COMMAND)
bdfd8d77 1997 bIsWaiting = FALSE;
bdfd8d77 1998 ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
239c2e96 1999 }
c82be69b 2000
61243a51 2001 wxCurrentPopupMenu = NULL;
61243a51
DW
2002 pMenu->SetInvokingWindow(NULL);
2003 return TRUE;
0367c1c0 2004} // end of wxWindowOS2::DoPopupMenu
19193a2c 2005#endif // wxUSE_MENUS_NATIVE
cdf1e714
DW
2006
2007// ===========================================================================
2008// pre/post message processing
2009// ===========================================================================
2010
0367c1c0 2011MRESULT wxWindowOS2::OS2DefWindowProc(
61243a51
DW
2012 WXUINT uMsg
2013, WXWPARAM wParam
2014, WXLPARAM lParam
2015)
cdf1e714 2016{
61243a51 2017 if (m_fnOldWndProc)
19193a2c 2018 return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
61243a51 2019 else
19193a2c 2020 return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
0367c1c0 2021} // end of wxWindowOS2::OS2DefWindowProc
cdf1e714 2022
0367c1c0 2023bool wxWindowOS2::OS2ProcessMessage(
61243a51
DW
2024 WXMSG* pMsg
2025)
cdf1e714 2026{
19193a2c
KB
2027// wxUniversal implements tab traversal itself
2028#ifndef __WXUNIVERSAL__
61243a51
DW
2029 QMSG* pQMsg = (QMSG*)pMsg;
2030
2031 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
2032 {
2033 //
2034 // Intercept dialog navigation keys
2035 //
2036 bool bProcess = TRUE;
2037 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
2038
2039 if (uKeyFlags & KC_KEYUP)
2040 bProcess = FALSE;
2041
2042 if (uKeyFlags & KC_ALT)
2043 bProcess = FALSE;
2044
2045 if (!(uKeyFlags & KC_VIRTUALKEY))
2046 bProcess = FALSE;
2047
2048 if (bProcess)
2049 {
2050 bool bCtrlDown = IsCtrlDown();
2051 bool bShiftDown = IsShiftDown();
2052
2053 //
2054 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
2055 // don't process it if it's the case (except for Ctrl-Tab/Enter
2056 // combinations which are always processed)
2057 //
2058 ULONG ulDlgCode = 0;
2059
2060 if (!bCtrlDown)
2061 {
2062 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
2063 }
2064
2065 bool bForward = TRUE;
2066 bool bWindowChange = FALSE;
2067
2068 switch (SHORT2FROMMP(pQMsg->mp2))
2069 {
2070 //
2071 // Going to make certain assumptions about specific types of controls
2072 // here, so we may have to alter some things later if they prove invalid
2073 //
2074 case VK_TAB:
2075 //
2076 // Shift tabl will always be a nav-key but tabs may be wanted
2077 //
2078 if (!bShiftDown)
2079 {
2080 bProcess = FALSE;
2081 }
2082 else
2083 {
2084 //
2085 // Entry Fields want tabs for themselve usually
2086 //
2087 switch (ulDlgCode)
2088 {
2089 case DLGC_ENTRYFIELD:
2090 case DLGC_MLE:
2091 bProcess = TRUE;
2092 break;
2093
2094 default:
2095 bProcess = FALSE;
2096 }
2097
2098 //
2099 // Ctrl-Tab cycles thru notebook pages
2100 //
2101 bWindowChange = bCtrlDown;
2102 bForward = !bShiftDown;
2103 }
2104 break;
2105
2106 case VK_UP:
2107 case VK_LEFT:
2108 if (bCtrlDown)
2109 bProcess = FALSE;
2110 else
2111 bForward = FALSE;
2112 break;
2113
2114 case VK_DOWN:
2115 case VK_RIGHT:
2116 if (bCtrlDown)
2117 bProcess = FALSE;
2118 break;
2119
2120 case VK_ENTER:
2121 {
2122 if (bCtrlDown)
2123 {
2124 //
2125 // ctrl-enter is not processed
2126 //
2127 return FALSE;
2128 }
2129 else if (ulDlgCode & DLGC_BUTTON)
2130 {
2131 //
2132 // buttons want process Enter themselevs
2133 //
2134 bProcess = FALSE;
2135 }
2136 else
2137 {
1bcfc0e1
DW
2138 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
2139 ,wxButton
2140 );
61243a51
DW
2141
2142 if (pBtn && pBtn->IsEnabled())
2143 {
2144 //
2145 // If we do have a default button, do press it
2146 //
2147 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
2148 return TRUE;
2149 }
2b5f62a0
VZ
2150 else if (!IsTopLevel())
2151 {
2152 //
2153 // if not a top level window, let parent
2154 // handle it
2155 //
2156 return FALSE;
2157 }
61243a51
DW
2158 // else: but if it does not it makes sense to make
2159 // it work like a TAB - and that's what we do.
2160 // Note that Ctrl-Enter always works this way.
2161 }
2162 }
2163 break;
2164
2165 default:
2166 bProcess = FALSE;
2167 }
2168
2169 if (bProcess)
2170 {
2171 wxNavigationKeyEvent vEvent;
2172
2173 vEvent.SetDirection(bForward);
2174 vEvent.SetWindowChange(bWindowChange);
2175 vEvent.SetEventObject(this);
2176
2177 if (GetEventHandler()->ProcessEvent(vEvent))
2178 {
2179 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2180
2181 if (pBtn)
2182 {
2183 //
2184 // The button which has focus should be default
2185 //
2186 pBtn->SetDefault();
2187 }
2188 return TRUE;
2189 }
2190 }
2191 }
dae16775
DW
2192 //
2193 // Let Dialogs process
2194 //
2195 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
2196 return TRUE;
61243a51 2197 }
19193a2c
KB
2198#else
2199 pMsg = pMsg; // just shut up the compiler
2200#endif // __WXUNIVERSAL__
61243a51 2201
cdf1e714 2202 return FALSE;
0367c1c0 2203} // end of wxWindowOS2::OS2ProcessMessage
cdf1e714 2204
0367c1c0 2205bool wxWindowOS2::OS2TranslateMessage(
61243a51
DW
2206 WXMSG* pMsg
2207)
cdf1e714 2208{
19193a2c 2209#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
7e99520b
DW
2210 return m_acceleratorTable.Translate(m_hWnd, pMsg);
2211#else
19193a2c 2212 pMsg = pMsg;
7e99520b
DW
2213 return FALSE;
2214#endif //wxUSE_ACCEL
0367c1c0 2215} // end of wxWindowOS2::OS2TranslateMessage
cdf1e714 2216
54ffa107
DW
2217bool wxWindowOS2::OS2ShouldPreProcessMessage(
2218 WXMSG* pMsg
2219)
2220{
2221 // preprocess all messages by default
2222 return TRUE;
2223} // end of wxWindowOS2::OS2ShouldPreProcessMessage
2224
cdf1e714 2225// ---------------------------------------------------------------------------
61243a51 2226// message params unpackers
cdf1e714
DW
2227// ---------------------------------------------------------------------------
2228
0367c1c0 2229void wxWindowOS2::UnpackCommand(
61243a51
DW
2230 WXWPARAM wParam
2231, WXLPARAM lParam
2232, WORD* pId
2233, WXHWND* phWnd
2234, WORD* pCmd
2235)
cdf1e714 2236{
5b3ed311
DW
2237 *pId = LOWORD(wParam);
2238 *phWnd = NULL; // or may be GetHWND() ?
2239 *pCmd = LOWORD(lParam);
0367c1c0 2240} // end of wxWindowOS2::UnpackCommand
cdf1e714 2241
0367c1c0 2242void wxWindowOS2::UnpackActivate(
61243a51
DW
2243 WXWPARAM wParam
2244, WXLPARAM lParam
2245, WXWORD* pState
2246, WXHWND* phWnd
2247)
cdf1e714 2248{
61243a51
DW
2249 *pState = LOWORD(wParam);
2250 *phWnd = (WXHWND)lParam;
0367c1c0 2251} // end of wxWindowOS2::UnpackActivate
cdf1e714 2252
0367c1c0 2253void wxWindowOS2::UnpackScroll(
61243a51
DW
2254 WXWPARAM wParam
2255, WXLPARAM lParam
2256, WXWORD* pCode
2257, WXWORD* pPos
2258, WXHWND* phWnd
2259)
cdf1e714 2260{
b7d8f285
DW
2261 ULONG ulId;
2262 HWND hWnd;
2263
2264 ulId = (ULONG)LONGFROMMP(wParam);
2265 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2266 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2267 *phWnd = NULLHANDLE;
2268 else
2269 *phWnd = hWnd;
2270
2271 *pPos = SHORT1FROMMP(lParam);
2272 *pCode = SHORT2FROMMP(lParam);
0367c1c0 2273} // end of wxWindowOS2::UnpackScroll
61243a51 2274
0367c1c0 2275void wxWindowOS2::UnpackMenuSelect(
61243a51
DW
2276 WXWPARAM wParam
2277, WXLPARAM lParam
2278, WXWORD* pItem
2279, WXWORD* pFlags
2280, WXHMENU* phMenu
2281)
cdf1e714 2282{
61243a51
DW
2283 *pItem = (WXWORD)LOWORD(wParam);
2284 *pFlags = HIWORD(wParam);
2285 *phMenu = (WXHMENU)lParam;
0367c1c0 2286} // end of wxWindowOS2::UnpackMenuSelect
cdf1e714
DW
2287
2288// ---------------------------------------------------------------------------
77ffb593 2289// Main wxWidgets window proc and the window proc for wxWindow
cdf1e714
DW
2290// ---------------------------------------------------------------------------
2291
61243a51 2292//
cdf1e714
DW
2293// Hook for new window just as it's being created, when the window isn't yet
2294// associated with the handle
61243a51 2295//
19193a2c 2296wxWindowOS2* wxWndHook = NULL;
cdf1e714 2297
61243a51 2298//
cdf1e714 2299// Main window proc
61243a51 2300//
f23208ca 2301MRESULT EXPENTRY wxWndProc(
61243a51
DW
2302 HWND hWnd
2303, ULONG ulMsg
2304, MPARAM wParam
2305, MPARAM lParam
2306)
cdf1e714 2307{
19193a2c 2308 wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
cdf1e714 2309
61243a51
DW
2310 //
2311 // When we get the first message for the HWND we just created, we associate
cdf1e714 2312 // it with wxWindow stored in wxWndHook
61243a51
DW
2313 //
2314 if (!pWnd && wxWndHook)
cdf1e714 2315 {
cdf1e714 2316 wxAssociateWinWithHandle(hWnd, wxWndHook);
61243a51 2317 pWnd = wxWndHook;
cdf1e714 2318 wxWndHook = NULL;
61243a51 2319 pWnd->SetHWND((WXHWND)hWnd);
cdf1e714
DW
2320 }
2321
5b3ed311 2322 MRESULT rc = (MRESULT)0;
e604d44b 2323
cdf1e714 2324
61243a51 2325 //
cdf1e714 2326 // Stop right here if we don't have a valid handle in our wxWindow object.
61243a51
DW
2327 //
2328 if (pWnd && !pWnd->GetHWND())
cdf1e714 2329 {
61243a51
DW
2330 pWnd->SetHWND((WXHWND) hWnd);
2331 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2332 pWnd->SetHWND(0);
cdf1e714
DW
2333 }
2334 else
2335 {
61243a51 2336 if (pWnd)
45e0dc94 2337 {
61243a51 2338 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
45e0dc94
DW
2339 if ( (pWnd->GetScrollBarHorz() != NULLHANDLE ||
2340 pWnd->GetScrollBarVert() != NULLHANDLE) &&
2341 ulMsg == WM_PAINT)
2342 {
2343 if (pWnd->GetScrollBarHorz() != NULLHANDLE)
2344 ::WinInvalidateRect(pWnd->GetScrollBarHorz(), NULL, TRUE);
2345 if (pWnd->GetScrollBarVert() != NULLHANDLE)
2346 ::WinInvalidateRect(pWnd->GetScrollBarVert(), NULL, TRUE);
2347 }
2348 }
e604d44b 2349 else
61243a51 2350 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
cdf1e714 2351 }
5b3ed311 2352
cdf1e714 2353 return rc;
61243a51 2354} // end of wxWndProc
cdf1e714 2355
61243a51
DW
2356//
2357// We will add (or delete) messages we need to handle at this default
2358// level as we go
2359//
0367c1c0 2360MRESULT wxWindowOS2::OS2WindowProc(
61243a51
DW
2361 WXUINT uMsg
2362, WXWPARAM wParam
2363, WXLPARAM lParam
2364)
cdf1e714 2365{
61243a51
DW
2366 //
2367 // Did we process the uMsg?
2368 //
2369 bool bProcessed = FALSE;
e604d44b 2370 MRESULT mResult;
cdf1e714 2371
61243a51
DW
2372 //
2373 // For most messages we should return 0 when we do process the message
2374 //
e604d44b 2375 mResult = (MRESULT)0;
61243a51
DW
2376
2377 switch (uMsg)
cdf1e714
DW
2378 {
2379 case WM_CREATE:
2380 {
61243a51
DW
2381 bool bMayCreate;
2382
2383 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2384 ,&bMayCreate
2385 );
2386 if (bProcessed)
cdf1e714 2387 {
61243a51
DW
2388 //
2389 // Return 0 to bAllow window creation
2390 //
e604d44b 2391 mResult = (MRESULT)(bMayCreate ? 0 : -1);
cdf1e714
DW
2392 }
2393 }
2394 break;
2395
2396 case WM_DESTROY:
e604d44b
DW
2397 HandleDestroy();
2398 bProcessed = TRUE;
e604d44b 2399 break;
cdf1e714
DW
2400
2401 case WM_MOVE:
61243a51
DW
2402 bProcessed = HandleMove( LOWORD(lParam)
2403 ,HIWORD(lParam)
2404 );
cdf1e714
DW
2405 break;
2406
2407 case WM_SIZE:
61243a51
DW
2408 bProcessed = HandleSize( LOWORD(lParam)
2409 ,HIWORD(lParam)
2410 ,(WXUINT)wParam
2411 );
cdf1e714
DW
2412 break;
2413
e37db699
DW
2414 case WM_WINDOWPOSCHANGED:
2415
2416 //
2417 // Dialogs under OS/2 do not get WM_SIZE events at all.
2418 // Instead they get this, which can function much like WM_SIZE
2419 // PSWP contains the new sizes and positioning, PSWP+1 the old
2420 // We use this because ADJUSTWINDOWPOS comes BEFORE the new
2421 // position is added and our auto layout does a WinQueryWindowRect
2422 // to get the CURRENT client size. That is the size used to position
2423 // child controls, so we need to already be sized
2424 // in order to get the child controls positoned properly.
2425 //
626af800 2426 if (IsKindOf(CLASSINFO(wxDialog)) || IsKindOf(CLASSINFO(wxFrame)))
e37db699
DW
2427 {
2428 PSWP pSwp = (PSWP)PVOIDFROMMP(wParam);
f3e4a2a4
DW
2429 PSWP pSwp2 = pSwp++;
2430
2431 if (!(pSwp->cx == pSwp2->cx &&
2432 pSwp->cy == pSwp2->cy))
2433 bProcessed = HandleSize( pSwp->cx
2434 ,pSwp->cy
2435 ,(WXUINT)lParam
2436 );
626af800
DW
2437 if (IsKindOf(CLASSINFO(wxFrame)))
2438 {
2439 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
2440
2441 if (pFrame)
2442 {
2443 if (pFrame->GetStatusBar())
2444 pFrame->PositionStatusBar();
2590f154
DW
2445 if (pFrame->GetToolBar())
2446 pFrame->PositionToolBar();
626af800
DW
2447 }
2448 }
e37db699
DW
2449 }
2450 break;
2451
cdf1e714
DW
2452 case WM_ACTIVATE:
2453 {
61243a51
DW
2454 WXWORD wState;
2455 WXHWND hWnd;
2456
2457 UnpackActivate( wParam
2458 ,lParam
2459 ,&wState
2460 ,&hWnd
2461 );
2462
2463 bProcessed = HandleActivate( wState
2464 ,(WXHWND)hWnd
2465 );
e604d44b 2466 bProcessed = FALSE;
cdf1e714
DW
2467 }
2468 break;
2469
2470 case WM_SETFOCUS:
61243a51
DW
2471 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2472 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2473 else
2474 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
cdf1e714
DW
2475 break;
2476
2477 case WM_PAINT:
61243a51 2478 bProcessed = HandlePaint();
cdf1e714
DW
2479 break;
2480
2481 case WM_CLOSE:
61243a51
DW
2482 //
2483 // Don't let the DefWindowProc() destroy our window - we'll do it
cdf1e714 2484 // ourselves in ~wxWindow
61243a51
DW
2485 //
2486 bProcessed = TRUE;
e604d44b 2487 mResult = (MRESULT)TRUE;
cdf1e714
DW
2488 break;
2489
61243a51
DW
2490 case WM_SHOW:
2491 bProcessed = HandleShow(wParam != 0, (int)lParam);
cdf1e714
DW
2492 break;
2493
61243a51
DW
2494 //
2495 // Under OS2 PM Joysticks are treated just like mouse events
2496 // The "Motion" events will be prevelent in joysticks
2497 //
cdf1e714 2498 case WM_MOUSEMOVE:
61243a51
DW
2499 case WM_BUTTON1DOWN:
2500 case WM_BUTTON1UP:
2501 case WM_BUTTON1DBLCLK:
2502 case WM_BUTTON1MOTIONEND:
2503 case WM_BUTTON1MOTIONSTART:
2504 case WM_BUTTON2DOWN:
2505 case WM_BUTTON2UP:
2506 case WM_BUTTON2DBLCLK:
2507 case WM_BUTTON2MOTIONEND:
2508 case WM_BUTTON2MOTIONSTART:
2509 case WM_BUTTON3DOWN:
2510 case WM_BUTTON3UP:
2511 case WM_BUTTON3DBLCLK:
2512 case WM_BUTTON3MOTIONEND:
2513 case WM_BUTTON3MOTIONSTART:
cdf1e714 2514 {
430974f8
DW
2515 if (uMsg == WM_BUTTON1DOWN && AcceptsFocus())
2516 SetFocus();
2517
2518 short nX = LOWORD(wParam);
2519 short nY = HIWORD(wParam);
cdf1e714 2520
430974f8
DW
2521 //
2522 // Redirect the event to a static control if necessary
2523 //
2524 if (this == GetCapture())
2525 {
2526 bProcessed = HandleMouseEvent( uMsg
2527 ,nX
2528 ,nY
8d902dd6 2529 ,(WXUINT)SHORT2FROMMP(lParam)
430974f8
DW
2530 );
2531 }
2532 else
2533 {
2534 wxWindow* pWin = FindWindowForMouseEvent( this
2535 ,&nX
2536 ,&nY
2537 );
376ef4a1
DW
2538 if (!pWin->IsOfStandardClass())
2539 {
2540 if (uMsg == WM_BUTTON1DOWN && pWin->AcceptsFocus() )
2541 pWin->SetFocus();
2542 }
430974f8
DW
2543 bProcessed = pWin->HandleMouseEvent( uMsg
2544 ,nX
2545 ,nY
8d902dd6 2546 ,(WXUINT)SHORT2FROMMP(lParam)
430974f8
DW
2547 );
2548 }
cdf1e714
DW
2549 }
2550 break;
430974f8 2551
cdf1e714 2552 case WM_SYSCOMMAND:
61243a51 2553 bProcessed = HandleSysCommand(wParam, lParam);
cdf1e714
DW
2554 break;
2555
2556 case WM_COMMAND:
2557 {
2558 WORD id, cmd;
2559 WXHWND hwnd;
2560 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2561
61243a51 2562 bProcessed = HandleCommand(id, cmd, hwnd);
cdf1e714
DW
2563 }
2564 break;
2565
61243a51
DW
2566 //
2567 // For these messages we must return TRUE if process the message
2568 //
cdf1e714
DW
2569 case WM_DRAWITEM:
2570 case WM_MEASUREITEM:
2571 {
45bedfdd 2572 int nIdCtrl = (UINT)wParam;
45bedfdd 2573
61243a51 2574 if ( uMsg == WM_DRAWITEM )
cdf1e714 2575 {
45bedfdd 2576 bProcessed = OS2OnDrawItem(nIdCtrl,
cdf1e714
DW
2577 (WXDRAWITEMSTRUCT *)lParam);
2578 }
2579 else
2580 {
f5ea767e
DW
2581 return MRFROMLONG(OS2OnMeasureItem( nIdCtrl
2582 ,(WXMEASUREITEMSTRUCT *)lParam
2583 ));
cdf1e714
DW
2584 }
2585
61243a51 2586 if ( bProcessed )
e604d44b 2587 mResult = (MRESULT)TRUE;
cdf1e714
DW
2588 }
2589 break;
2590
61243a51 2591 case WM_QUERYDLGCODE:
47df2b8c 2592 if (!IsOfStandardClass())
cdf1e714 2593 {
47df2b8c
DW
2594 if ( m_lDlgCode )
2595 {
2596 mResult = (MRESULT)m_lDlgCode;
2597 bProcessed = TRUE;
2598 }
cdf1e714 2599 }
61243a51 2600 //
cdf1e714 2601 //else: get the dlg code from the DefWindowProc()
61243a51 2602 //
cdf1e714
DW
2603 break;
2604
61243a51
DW
2605 //
2606 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2607 // and key-down events are obtained from the WM_CHAR params.
2608 //
2609 case WM_CHAR:
cdf1e714 2610 {
61243a51 2611 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 2612
61243a51
DW
2613 if (uKeyFlags & KC_KEYUP)
2614 {
19193a2c 2615 //TODO: check if the cast to WXWORD isn't causing trouble
a086de98 2616 bProcessed = HandleKeyUp(wParam, lParam);
cdf1e714 2617 break;
61243a51
DW
2618 }
2619 else // keydown event
2620 {
3437f881 2621 m_bLastKeydownProcessed = FALSE;
61243a51
DW
2622 //
2623 // If this has been processed by an event handler,
2624 // return 0 now (we've handled it). DON't RETURN
2625 // we still need to process further
2626 //
a086de98 2627 m_bLastKeydownProcessed = HandleKeyDown(wParam, lParam);
61243a51 2628 if (uKeyFlags & KC_VIRTUALKEY)
cdf1e714 2629 {
61243a51
DW
2630 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2631
2632 //
2633 // We consider these message "not interesting" to OnChar
2634 //
61243a51
DW
2635 switch(uVk)
2636 {
a086de98
DW
2637 case VK_SHIFT:
2638 case VK_CTRL:
2639 case VK_MENU:
2640 case VK_CAPSLOCK:
2641 case VK_NUMLOCK:
2642 case VK_SCRLLOCK:
2643 bProcessed = TRUE;
2644 break;
2645
61243a51
DW
2646 // Avoid duplicate messages to OnChar for these ASCII keys: they
2647 // will be translated by TranslateMessage() and received in WM_CHAR
2648 case VK_ESC:
61243a51
DW
2649 case VK_ENTER:
2650 case VK_BACKSPACE:
2651 case VK_TAB:
2652 // But set processed to FALSE, not TRUE to still pass them to
2653 // the control's default window proc - otherwise built-in
2654 // keyboard handling won't work
2655 bProcessed = FALSE;
2656 break;
2657
61243a51 2658 default:
598d8cac 2659 bProcessed = HandleChar(wParam, lParam);
61243a51
DW
2660 }
2661 break;
cdf1e714 2662 }
61243a51
DW
2663 else // WM_CHAR -- Always an ASCII character
2664 {
a086de98
DW
2665 if (m_bLastKeydownProcessed)
2666 {
2667 //
2668 // The key was handled in the EVT_KEY_DOWN and handling
2669 // a key in an EVT_KEY_DOWN handler is meant, by
2670 // design, to prevent EVT_CHARs from happening
2671 //
2672 m_bLastKeydownProcessed = FALSE;
2673 bProcessed = TRUE;
2674 }
2675 else // do generate a CHAR event
2676 {
598d8cac 2677 bProcessed = HandleChar(wParam, lParam, TRUE);
a086de98
DW
2678 break;
2679 }
61243a51
DW
2680 }
2681 }
cdf1e714 2682 }
cdf1e714
DW
2683
2684 case WM_HSCROLL:
2685 case WM_VSCROLL:
2686 {
61243a51
DW
2687 WXWORD wCode;
2688 WXWORD wPos;
2689 WXHWND hWnd;
2690 UnpackScroll( wParam
2691 ,lParam
2692 ,&wCode
2693 ,&wPos
2694 ,&hWnd
2695 );
2696
2697 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2698 : wxVERTICAL
2699 ,wCode
2700 ,wPos
2701 ,hWnd
2702 );
cdf1e714
DW
2703 }
2704 break;
2705
3c299c3a
DW
2706 case WM_CONTROL:
2707 switch(SHORT2FROMMP(wParam))
2708 {
a5799260
DW
2709 case BN_PAINT:
2710 {
2711 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2712 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2713
2714 if (!pWin)
2715 {
2716 bProcessed = FALSE;
2717 break;
2718 }
2719 if (pWin->IsKindOf(CLASSINFO(wxBitmapButton)))
2720 {
2721 wxBitmapButton* pBitmapButton = wxDynamicCast(pWin, wxBitmapButton);
2722
2723 pBitmapButton->OS2OnDraw((WXDRAWITEMSTRUCT *)lParam);
2724 }
2725 return 0;
2726 }
2727 break;
2728
1de4baa3
DW
2729 case BKN_PAGESELECTEDPENDING:
2730 {
2731 PPAGESELECTNOTIFY pPage = (PPAGESELECTNOTIFY)lParam;
2732
2733 if ((pPage->ulPageIdNew != pPage->ulPageIdCur) &&
2734 (pPage->ulPageIdNew > 0L && pPage->ulPageIdCur > 0L))
2735 {
2736 wxWindowOS2* pWin = wxFindWinFromHandle(pPage->hwndBook);
2737 wxNotebookEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
2738 ,(int)SHORT1FROMMP(wParam)
2739 ,(int)pPage->ulPageIdNew
2740 ,(int)pPage->ulPageIdCur
2741 );
2742 if (!pWin)
2743 {
2744 bProcessed = FALSE;
2745 break;
2746 }
2747 if (pWin->IsKindOf(CLASSINFO(wxNotebook)))
2748 {
2749 wxNotebook* pNotebook = wxDynamicCast(pWin, wxNotebook);
2750
2751 vEvent.SetEventObject(pWin);
2752 pNotebook->OnSelChange(vEvent);
2753 bProcessed = TRUE;
2754 }
2755 else
2756 bProcessed = FALSE;
2757 }
2758 else
2759 bProcessed = FALSE;
2760 }
2761 break;
2762
2763 case BN_CLICKED: // Dups as LN_SELECT and CBN_LBSELECT
f289196b
DW
2764 {
2765 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2766 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2767
2768 if (!pWin)
2769 {
2770 bProcessed = FALSE;
2771 break;
2772 }
2773 //
77ffb593 2774 // Simulate a WM_COMMAND here, as wxWidgets expects all control
f289196b
DW
2775 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2776 //
2777 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
2778 {
2779 wxRadioBox* pRadioBox = wxDynamicCast(pWin, wxRadioBox);
2780
2781 pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2782 ,(WXUINT)SHORT1FROMMP(wParam)
2783 );
2784 }
2785 if (pWin->IsKindOf(CLASSINFO(wxRadioButton)))
2786 {
2787 wxRadioButton* pRadioButton = wxDynamicCast(pWin, wxRadioButton);
2788
2789 pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2790 ,(WXUINT)SHORT1FROMMP(wParam)
2791 );
2792 }
2793 if (pWin->IsKindOf(CLASSINFO(wxCheckBox)))
2794 {
2795 wxCheckBox* pCheckBox = wxDynamicCast(pWin, wxCheckBox);
2796
2797 pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2798 ,(WXUINT)SHORT1FROMMP(wParam)
2799 );
2800 }
1de4baa3
DW
2801 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2802 {
2803 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2804
2805 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2806 ,(WXUINT)SHORT1FROMMP(wParam)
2807 );
2808 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2809 Refresh();
2810 }
2811 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2812 {
2813 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2814
2815 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2816 ,(WXUINT)SHORT1FROMMP(wParam)
2817 );
2818 }
2819 return 0;
2820 }
2821 break;
2822
2823 case LN_ENTER: /* dups as CBN_EFCHANGE */
2824 {
2825 HWND hWnd = HWNDFROMMP(lParam);
2826 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2827
2828 if (!pWin)
2829 {
2830 bProcessed = FALSE;
2831 break;
2832 }
2833 //
77ffb593 2834 // Simulate a WM_COMMAND here, as wxWidgets expects all control
1de4baa3
DW
2835 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2836 //
2837 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2838 {
2839 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2840
2841 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2842 ,(WXUINT)SHORT1FROMMP(wParam)
2843 );
2844 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2845 Refresh();
2846
2847 }
2848 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2849 {
2850 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2851
2852 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2853 ,(WXUINT)SHORT1FROMMP(wParam)
2854 );
2855 }
f289196b
DW
2856 return 0;
2857 }
2858 break;
2859
3c299c3a
DW
2860 case SPBN_UPARROW:
2861 case SPBN_DOWNARROW:
2862 case SPBN_CHANGE:
2863 {
2864 char zVal[10];
2865 long lVal;
2866
2867 ::WinSendMsg( HWNDFROMMP(lParam)
2868 ,SPBM_QUERYVALUE
2869 ,&zVal
2870 ,MPFROM2SHORT( (USHORT)10
2871 ,(USHORT)SPBQ_UPDATEIFVALID
2872 )
2873 );
2874 lVal = atol(zVal);
2875 bProcessed = OS2OnScroll( wxVERTICAL
2876 ,(int)SHORT2FROMMP(wParam)
2877 ,(int)lVal
2878 ,HWNDFROMMP(lParam)
2879 );
2880 }
2881 break;
2882
2883 case SLN_SLIDERTRACK:
2884 {
2885 HWND hWnd = ::WinWindowFromID(GetHWND(), SHORT1FROMMP(wParam));
2886 wxWindowOS2* pChild = wxFindWinFromHandle(hWnd);
2887
b389a12d
DW
2888 if (!pChild)
2889 {
2890 bProcessed = FALSE;
2891 break;
2892 }
3c299c3a
DW
2893 if (pChild->IsKindOf(CLASSINFO(wxSlider)))
2894 bProcessed = OS2OnScroll( wxVERTICAL
2895 ,(int)SHORT2FROMMP(wParam)
2896 ,(int)LONGFROMMP(lParam)
2897 ,hWnd
2898 );
2899 }
2900 break;
2901 }
2902 break;
2903
61243a51
DW
2904#if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2905 case WM_CTLCOLORCHANGE:
cdf1e714 2906 {
e604d44b 2907 bProcessed = HandleCtlColor(&hBrush);
61243a51
DW
2908 }
2909 break;
2910#endif
8d854fa9
DW
2911 case WM_ERASEBACKGROUND:
2912 //
2913 // Returning TRUE to requestw PM to paint the window background
2914 // in SYSCLR_WINDOW. We don't really want that
2915 //
2916 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2917 mResult = (MRESULT)(FALSE);
2918 break;
2919
cdf1e714
DW
2920 // the return value for this message is ignored
2921 case WM_SYSCOLORCHANGE:
61243a51 2922 bProcessed = HandleSysColorChange();
cdf1e714
DW
2923 break;
2924
61243a51
DW
2925 case WM_REALIZEPALETTE:
2926 bProcessed = HandlePaletteChanged();
cdf1e714
DW
2927 break;
2928
61243a51
DW
2929 // move all drag and drops to wxDrg
2930 case WM_ENDDRAG:
2931 bProcessed = HandleEndDrag(wParam);
cdf1e714
DW
2932 break;
2933
61243a51
DW
2934 case WM_INITDLG:
2935 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
cdf1e714 2936
61243a51 2937 if ( bProcessed )
cdf1e714
DW
2938 {
2939 // we never set focus from here
272ebf16 2940 mResult = (MRESULT)FALSE;
cdf1e714
DW
2941 }
2942 break;
2943
61243a51
DW
2944 // wxFrame specific message
2945 case WM_MINMAXFRAME:
f6bcfd97 2946 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
cdf1e714
DW
2947 break;
2948
61243a51
DW
2949 case WM_SYSVALUECHANGED:
2950 // TODO: do something
e604d44b 2951 mResult = (MRESULT)TRUE;
cdf1e714
DW
2952 break;
2953
61243a51
DW
2954 //
2955 // Comparable to WM_SETPOINTER for windows, only for just controls
2956 //
2957 case WM_CONTROLPOINTER:
2958 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2959 ,(HWND)lParam // Cursor Handle
2960 );
2961 if (bProcessed )
cdf1e714 2962 {
61243a51
DW
2963 //
2964 // Returning TRUE stops the DefWindowProc() from further
cdf1e714
DW
2965 // processing this message - exactly what we need because we've
2966 // just set the cursor.
61243a51 2967 //
e604d44b 2968 mResult = (MRESULT)TRUE;
cdf1e714
DW
2969 }
2970 break;
c82be69b
JS
2971
2972#if wxUSE_MENUS_NATIVE
2973 case WM_MENUEND:
2974 if (wxCurrentPopupMenu)
2975 {
2976 if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
2977 {
2978 // Break out of msg loop in DoPopupMenu
2979 ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
2980 }
2981 }
2982 break;
2983#endif // wxUSE_MENUS_NATIVE
2984
cdf1e714 2985 }
61243a51 2986 if (!bProcessed)
cdf1e714
DW
2987 {
2988#ifdef __WXDEBUG__
2989 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
61243a51 2990 wxGetMessageName(uMsg));
cdf1e714 2991#endif // __WXDEBUG__
d08f23a7
DW
2992 if (IsKindOf(CLASSINFO(wxFrame)))
2993 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
1b086de1
DW
2994 else if (IsKindOf(CLASSINFO(wxDialog)))
2995 mResult = ::WinDefDlgProc( m_hWnd, uMsg, wParam, lParam);
d08f23a7
DW
2996 else
2997 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
cdf1e714 2998 }
e604d44b 2999 return mResult;
0367c1c0 3000} // end of wxWindowOS2::OS2WindowProc
cdf1e714 3001
2461cfa0
SN
3002// ----------------------------------------------------------------------------
3003// wxWindow <-> HWND map
3004// ----------------------------------------------------------------------------
3005
3006wxWinHashTable *wxWinHandleHash = NULL;
3007
61243a51
DW
3008wxWindow* wxFindWinFromHandle(
3009 WXHWND hWnd
3010)
cdf1e714 3011{
2461cfa0 3012 return (wxWindow *)wxWinHandleHash->Get((long)hWnd);
61243a51 3013} // end of wxFindWinFromHandle
cdf1e714 3014
61243a51
DW
3015void wxAssociateWinWithHandle(
3016 HWND hWnd
19193a2c 3017, wxWindowOS2* pWin
61243a51 3018)
cdf1e714 3019{
61243a51
DW
3020 //
3021 // Adding NULL hWnd is (first) surely a result of an error and
cdf1e714 3022 // (secondly) breaks menu command processing
61243a51 3023 //
cdf1e714
DW
3024 wxCHECK_RET( hWnd != (HWND)NULL,
3025 wxT("attempt to add a NULL hWnd to window list ignored") );
3026
3027
61243a51
DW
3028 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
3029
3030 if (pOldWin && (pOldWin != pWin))
cdf1e714 3031 {
61243a51
DW
3032 wxString str(pWin->GetClassInfo()->GetClassName());
3033 wxLogError( "Bug! Found existing HWND %X for new window of class %s"
3034 ,(int)hWnd
3035 ,(const char*)str
3036 );
cdf1e714 3037 }
61243a51 3038 else if (!pOldWin)
cdf1e714 3039 {
2461cfa0
SN
3040 wxWinHandleHash->Put( (long)hWnd
3041 ,(wxWindow *)pWin
3042 );
cdf1e714 3043 }
61243a51 3044} // end of wxAssociateWinWithHandle
cdf1e714 3045
61243a51 3046void wxRemoveHandleAssociation(
19193a2c 3047 wxWindowOS2* pWin
61243a51 3048)
cdf1e714 3049{
2461cfa0 3050 wxWinHandleHash->Delete((long)pWin->GetHWND());
61243a51 3051} // end of wxRemoveHandleAssociation
cdf1e714 3052
61243a51 3053//
cdf1e714
DW
3054// Default destroyer - override if you destroy it in some other way
3055// (e.g. with MDI child windows)
61243a51 3056//
0367c1c0 3057void wxWindowOS2::OS2DestroyWindow()
cdf1e714
DW
3058{
3059}
3060
f9efbe3a
DW
3061bool wxWindowOS2::OS2GetCreateWindowCoords(
3062 const wxPoint& rPos
3063, const wxSize& rSize
3064, int& rnX
3065, int& rnY
3066, int& rnWidth
3067, int& rnHeight
3068) const
3069{
3070 bool bNonDefault = FALSE;
d697657f
DW
3071 static const int DEFAULT_Y = 200;
3072 static const int DEFAULT_H = 250;
f9efbe3a
DW
3073
3074 if (rPos.x == -1)
3075 {
f9efbe3a
DW
3076 rnX = rnY = CW_USEDEFAULT;
3077 }
3078 else
3079 {
3080 rnX = rPos.x;
d697657f 3081 rnY = rPos.y == -1 ? DEFAULT_Y : rPos.y;
f9efbe3a
DW
3082 bNonDefault = TRUE;
3083 }
3084 if (rSize.x == -1)
3085 {
f9efbe3a
DW
3086 rnWidth = rnHeight = CW_USEDEFAULT;
3087 }
3088 else
3089 {
3090 rnWidth = rSize.x;
d697657f 3091 rnHeight = rSize.y == -1 ? DEFAULT_H : rSize.y;
f9efbe3a
DW
3092 bNonDefault = TRUE;
3093 }
3094 return bNonDefault;
3095} // end of wxWindowOS2::OS2GetCreateWindowCoords
3096
6ed98c6a
DW
3097WXHWND wxWindowOS2::OS2GetParent() const
3098{
3099 return m_parent ? m_parent->GetHWND() : NULL;
3100}
3101
0367c1c0 3102bool wxWindowOS2::OS2Create(
5d44b24e
DW
3103 PSZ zClass
3104, const char* zTitle
61243a51 3105, WXDWORD dwStyle
5d44b24e
DW
3106, const wxPoint& rPos
3107, const wxSize& rSize
f23208ca 3108, void* pCtlData
008089f6 3109, WXDWORD dwExStyle
5d44b24e 3110, bool bIsChild
61243a51
DW
3111)
3112{
914589c2
DW
3113 ERRORID vError;
3114 wxString sError;
5d44b24e
DW
3115 int nX = 0L;
3116 int nY = 0L;
3117 int nWidth = 0L;
3118 int nHeight = 0L;
5d44b24e
DW
3119 long lControlId = 0L;
3120 wxWindowCreationHook vHook(this);
3121 wxString sClassName((wxChar*)zClass);
3122
3123 OS2GetCreateWindowCoords( rPos
3124 ,rSize
3125 ,nX
3126 ,nY
3127 ,nWidth
3128 ,nHeight
3129 );
3130
5d44b24e 3131 if (bIsChild)
cdf1e714 3132 {
5d44b24e
DW
3133 lControlId = GetId();
3134 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
cdf1e714 3135 {
5d44b24e 3136 dwStyle |= WS_CLIPSIBLINGS;
cdf1e714
DW
3137 }
3138 }
cd212ee4 3139 //
5d44b24e
DW
3140 // For each class "Foo" we have we also have "FooNR" ("no repaint") class
3141 // which is the same but without CS_[HV]REDRAW class styles so using it
3142 // ensures that the window is not fully repainted on each resize
e604d44b 3143 //
020172f6 3144 if (!HasFlag(wxFULL_REPAINT_ON_RESIZE))
51c1d535 3145 {
5d44b24e
DW
3146 sClassName += wxT("NR");
3147 }
6ed98c6a
DW
3148 m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
3149 ,(PSZ)sClassName.c_str()
3150 ,(PSZ)zTitle ? zTitle : ""
3151 ,(ULONG)dwStyle
3152 ,(LONG)0L
3153 ,(LONG)0L
3154 ,(LONG)0L
3155 ,(LONG)0L
3156 ,NULLHANDLE
3157 ,HWND_TOP
3158 ,(ULONG)lControlId
3159 ,pCtlData
3160 ,NULL
3161 );
5d44b24e
DW
3162 if (!m_hWnd)
3163 {
3164 vError = ::WinGetLastError(wxGetInstance());
3165 sError = wxPMErrorToStr(vError);
3166 return FALSE;
51c1d535 3167 }
5d44b24e 3168 SubclassWin(m_hWnd);
a756f210 3169 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
4a46a5df
DW
3170
3171 m_backgroundColour.Set(wxString("GREY"));
3172
3173 LONG lColor = (LONG)m_backgroundColour.GetPixel();
3174
3175 if (!::WinSetPresParam( m_hWnd
3176 ,PP_BACKGROUNDCOLOR
3177 ,sizeof(LONG)
3178 ,(PVOID)&lColor
3179 ))
3180 {
3181 vError = ::WinGetLastError(vHabmain);
3182 sError = wxPMErrorToStr(vError);
283ed244 3183 wxLogError("Error creating frame. Error: %s\n", sError.c_str());
4a46a5df
DW
3184 return FALSE;
3185 }
5d44b24e
DW
3186 SetSize( nX
3187 ,nY
3188 ,nWidth
3189 ,nHeight
3190 );
cdf1e714 3191 return TRUE;
5d44b24e 3192} // end of WinGuiBase_Window::OS2Create
cdf1e714
DW
3193
3194// ===========================================================================
3195// OS2 PM message handlers
3196// ===========================================================================
3197
3198// ---------------------------------------------------------------------------
61243a51 3199// window creation/destruction
cdf1e714
DW
3200// ---------------------------------------------------------------------------
3201
0367c1c0 3202bool wxWindowOS2::HandleCreate(
19193a2c 3203 WXLPCREATESTRUCT WXUNUSED(vCs)
61243a51
DW
3204, bool* pbMayCreate
3205)
cdf1e714 3206{
19193a2c 3207 wxWindowCreateEvent vEvent((wxWindow*)this);
cdf1e714 3208
61243a51
DW
3209 (void)GetEventHandler()->ProcessEvent(vEvent);
3210 *pbMayCreate = TRUE;
cdf1e714 3211 return TRUE;
0367c1c0 3212} // end of wxWindowOS2::HandleCreate
cdf1e714 3213
0367c1c0 3214bool wxWindowOS2::HandleDestroy()
cdf1e714 3215{
6e348b12
DW
3216 wxWindowDestroyEvent vEvent((wxWindow*)this);
3217 vEvent.SetId(GetId());
3218 (void)GetEventHandler()->ProcessEvent(vEvent);
61243a51
DW
3219
3220 //
3221 // Delete our drop target if we've got one
3222 //
cdf1e714 3223#if wxUSE_DRAG_AND_DROP
61243a51 3224 if (m_dropTarget != NULL)
cdf1e714 3225 {
cdf1e714
DW
3226 delete m_dropTarget;
3227 m_dropTarget = NULL;
3228 }
3229#endif // wxUSE_DRAG_AND_DROP
3230
61243a51 3231 //
cdf1e714 3232 // WM_DESTROY handled
61243a51 3233 //
cdf1e714 3234 return TRUE;
0367c1c0 3235} // end of wxWindowOS2::HandleDestroy
cdf1e714
DW
3236
3237// ---------------------------------------------------------------------------
3238// activation/focus
3239// ---------------------------------------------------------------------------
0367c1c0 3240void wxWindowOS2::OnSetFocus(
61243a51
DW
3241 wxFocusEvent& rEvent
3242)
cdf1e714 3243{
61243a51 3244 rEvent.Skip();
0367c1c0 3245} // end of wxWindowOS2::OnSetFocus
61243a51 3246
0367c1c0 3247bool wxWindowOS2::HandleActivate(
61243a51
DW
3248 int nState
3249, WXHWND WXUNUSED(hActivate)
3250)
3251{
3252 wxActivateEvent vEvent( wxEVT_ACTIVATE
3253 ,(bool)nState
3254 ,m_windowId
3255 );
3256 vEvent.SetEventObject(this);
3257 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3258} // end of wxWindowOS2::HandleActivate
61243a51 3259
0367c1c0 3260bool wxWindowOS2::HandleSetFocus(
61243a51
DW
3261 WXHWND WXUNUSED(hWnd)
3262)
cdf1e714 3263{
54ffa107
DW
3264 //
3265 // Notify the parent keeping track of focus for the kbd navigation
3266 // purposes that we got it
3267 //
3268 wxChildFocusEvent vEventFocus((wxWindow *)this);
3269 (void)GetEventHandler()->ProcessEvent(vEventFocus);
3270
cdf1e714 3271#if wxUSE_CARET
61243a51 3272 //
cdf1e714 3273 // Deal with caret
61243a51
DW
3274 //
3275 if (m_caret)
cdf1e714
DW
3276 {
3277 m_caret->OnSetFocus();
3278 }
3279#endif // wxUSE_CARET
3280
1bcfc0e1
DW
3281#if wxUSE_TEXTCTRL
3282 // If it's a wxTextCtrl don't send the event as it will be done
3283 // after the control gets to process it from EN_FOCUS handler
3284 if ( wxDynamicCastThis(wxTextCtrl) )
cdf1e714 3285 {
1bcfc0e1 3286 return FALSE;
cdf1e714 3287 }
1bcfc0e1 3288#endif // wxUSE_TEXTCTRL
cdf1e714 3289
61243a51 3290 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
cdf1e714 3291
61243a51
DW
3292 vEvent.SetEventObject(this);
3293 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3294} // end of wxWindowOS2::HandleSetFocus
cdf1e714 3295
0367c1c0 3296bool wxWindowOS2::HandleKillFocus(
a23692f0 3297 WXHWND hWnd
61243a51 3298)
cdf1e714
DW
3299{
3300#if wxUSE_CARET
61243a51 3301 //
cdf1e714 3302 // Deal with caret
61243a51
DW
3303 //
3304 if (m_caret)
cdf1e714
DW
3305 {
3306 m_caret->OnKillFocus();
3307 }
3308#endif // wxUSE_CARET
3309
a23692f0 3310#if wxUSE_TEXTCTRL
f289196b 3311 //
a23692f0
DW
3312 // If it's a wxTextCtrl don't send the event as it will be done
3313 // after the control gets to process it.
3314 //
3315 wxTextCtrl* pCtrl = wxDynamicCastThis(wxTextCtrl);
3316
3317 if (pCtrl)
3318 {
3319 return FALSE;
3320 }
3321#endif
3322
f289196b 3323 //
a23692f0
DW
3324 // Don't send the event when in the process of being deleted. This can
3325 // only cause problems if the event handler tries to access the object.
3326 //
3327 if ( m_isBeingDeleted )
3328 {
3329 return FALSE;
3330 }
3331
61243a51
DW
3332 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
3333 ,m_windowId
3334 );
cdf1e714 3335
61243a51 3336 vEvent.SetEventObject(this);
a23692f0 3337
f289196b 3338 //
a23692f0
DW
3339 // wxFindWinFromHandle() may return NULL, it is ok
3340 //
3341 vEvent.SetWindow(wxFindWinFromHandle(hWnd));
61243a51 3342 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3343} // end of wxWindowOS2::HandleKillFocus
cdf1e714
DW
3344
3345// ---------------------------------------------------------------------------
3346// miscellaneous
3347// ---------------------------------------------------------------------------
3348
0367c1c0 3349bool wxWindowOS2::HandleShow(
61243a51 3350 bool bShow
19193a2c 3351, int WXUNUSED(nStatus)
61243a51 3352)
cdf1e714 3353{
19193a2c 3354 wxShowEvent vEvent(GetId(), bShow);
cdf1e714 3355
687706f5 3356 vEvent.SetEventObject(this);
61243a51 3357 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3358} // end of wxWindowOS2::HandleShow
cdf1e714 3359
0367c1c0 3360bool wxWindowOS2::HandleInitDialog(
61243a51
DW
3361 WXHWND WXUNUSED(hWndFocus)
3362)
cdf1e714 3363{
61243a51 3364 wxInitDialogEvent vEvent(GetId());
cdf1e714 3365
687706f5 3366 vEvent.SetEventObject(this);
61243a51 3367 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3368} // end of wxWindowOS2::HandleInitDialog
cdf1e714 3369
19193a2c 3370bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
cdf1e714 3371{
61243a51 3372 // TODO: We'll handle drag and drop later
cdf1e714
DW
3373 return FALSE;
3374}
3375
0367c1c0 3376bool wxWindowOS2::HandleSetCursor(
19193a2c 3377 USHORT WXUNUSED(vId)
61243a51
DW
3378, WXHWND hPointer
3379)
cdf1e714 3380{
61243a51
DW
3381 //
3382 // Under OS/2 PM this allows the pointer to be changed
3383 // as it passes over a control
3384 //
3385 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
3386 return TRUE;
0367c1c0 3387} // end of wxWindowOS2::HandleSetCursor
cdf1e714
DW
3388
3389// ---------------------------------------------------------------------------
3390// owner drawn stuff
3391// ---------------------------------------------------------------------------
0367c1c0 3392bool wxWindowOS2::OS2OnDrawItem(
61243a51
DW
3393 int vId
3394, WXDRAWITEMSTRUCT* pItemStruct
3395)
cdf1e714 3396{
19193a2c 3397#if wxUSE_OWNER_DRAWN
402e2f7c 3398 wxDC vDc;
61243a51 3399
19193a2c 3400#if wxUSE_MENUS_NATIVE
61243a51 3401 //
402e2f7c 3402 // Is it a menu item?
61243a51 3403 //
402e2f7c
DW
3404 if (vId == 0)
3405 {
5afb9458
DW
3406 ERRORID vError;
3407 wxString sError;
402e2f7c 3408 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
23122f8c
DW
3409 wxFrame* pFrame = (wxFrame*)this;
3410 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
402e2f7c 3411 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
23122f8c
DW
3412 wxRect vRect( pMeasureStruct->rclItem.xLeft
3413 ,pMeasureStruct->rclItem.yBottom
3414 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3415 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3416 );
402e2f7c
DW
3417 vDc.SetHDC( hDC
3418 ,FALSE
3419 );
3420 vDc.SetHPS(pMeasureStruct->hps);
5afb9458 3421 //
77ffb593 3422 // Load the wxWidgets Pallete and set to RGB mode
5afb9458
DW
3423 //
3424 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3425 ,0L
3426 ,LCOLF_CONSECRGB
3427 ,0L
3428 ,(LONG)wxTheColourDatabase->m_nSize
3429 ,(PLONG)wxTheColourDatabase->m_palTable
3430 ))
3431 {
3432 vError = ::WinGetLastError(vHabmain);
3433 sError = wxPMErrorToStr(vError);
283ed244 3434 wxLogError("Unable to set current color table. Error: %s\n", sError.c_str());
5afb9458
DW
3435 }
3436 //
3437 // Set the color table to RGB mode
3438 //
3439 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3440 ,0L
3441 ,LCOLF_RGB
3442 ,0L
3443 ,0L
3444 ,NULL
3445 ))
3446 {
3447 vError = ::WinGetLastError(vHabmain);
3448 sError = wxPMErrorToStr(vError);
283ed244 3449 wxLogError("Unable to set current color table. Error: %s\n", sError.c_str());
5afb9458 3450 }
cdf1e714 3451
23122f8c
DW
3452 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3453
3454
3455 int eAction = 0;
3456 int eStatus = 0;
cdf1e714 3457
402e2f7c 3458 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
23122f8c
DW
3459 {
3460 //
3461 // Entire Item needs to be redrawn (either it has reappeared from
3462 // behind another window or is being displayed for the first time
3463 //
402e2f7c 3464 eAction = wxOwnerDrawn::wxODDrawAll;
23122f8c
DW
3465
3466 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3467 {
3468 //
3469 // If it is currently selected we let the system handle it
3470 //
3471 eStatus |= wxOwnerDrawn::wxODSelected;
3472 }
3473 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3474 {
3475 //
3476 // If it is currently checked we draw our own
3477 //
3478 eStatus |= wxOwnerDrawn::wxODChecked;
3479 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3480 }
3481 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3482 {
3483 //
3484 // If it is currently disabled we let the system handle it
3485 //
3486 eStatus |= wxOwnerDrawn::wxODDisabled;
3487 }
3488 //
3489 // Don't really care about framed (indicationg focus) or NoDismiss
3490 //
3491 }
402e2f7c 3492 else
23122f8c 3493 {
5afb9458
DW
3494 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3495 {
3496 eAction = wxOwnerDrawn::wxODDrawAll;
3497 eStatus |= wxOwnerDrawn::wxODSelected;
3498 //
3499 // Keep the system from trying to highlight with its bogus colors
3500 //
3501 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3502 }
3503 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3504 {
3505 eAction = wxOwnerDrawn::wxODDrawAll;
3506 eStatus = 0;
3507 //
3508 // Keep the system from trying to highlight with its bogus colors
3509 //
3510 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3511 }
3512 else
3513 {
3514 //
3515 // For now we don't care about anything else
3516 // just ignore the entire message!
3517 //
3518 return TRUE;
3519 }
23122f8c
DW
3520 }
3521 //
3522 // Now redraw the item
3523 //
45bedfdd
DW
3524 return(pMenuItem->OnDrawItem( vDc
3525 ,vRect
23122f8c
DW
3526 ,(wxOwnerDrawn::wxODAction)eAction
3527 ,(wxOwnerDrawn::wxODStatus)eStatus
45bedfdd 3528 ));
402e2f7c
DW
3529 //
3530 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3531 // the system will do the highlight or fraeming or disabling for us,
3532 // otherwise, we'd have to do it ourselves.
61243a51 3533 //
cdf1e714 3534 }
19193a2c 3535#endif // wxUSE_MENUS_NATIVE
cdf1e714 3536
402e2f7c
DW
3537 wxWindow* pItem = FindItem(vId);
3538
3539 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3540 {
3541 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3542 }
19193a2c
KB
3543#else
3544 vId = vId;
3545 pItemStruct = pItemStruct;
61243a51 3546#endif
402e2f7c 3547 return FALSE;
0367c1c0 3548} // end of wxWindowOS2::OS2OnDrawItem
cdf1e714 3549
f5ea767e 3550long wxWindowOS2::OS2OnMeasureItem(
402e2f7c
DW
3551 int lId
3552, WXMEASUREITEMSTRUCT* pItemStruct
3553)
0e320a79 3554{
19193a2c 3555#if wxUSE_OWNER_DRAWN
402e2f7c
DW
3556 //
3557 // Is it a menu item?
3558 //
45bedfdd 3559 if (lId == 65536) // I really don't like this...has to be a better indicator
cdf1e714 3560 {
4049cc1c 3561 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
45bedfdd 3562 {
4049cc1c
DW
3563 size_t nWidth;
3564 size_t nHeight;
3565 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
45bedfdd
DW
3566 wxFrame* pFrame = (wxFrame*)this;
3567 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
cdf1e714 3568
45bedfdd 3569 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
4049cc1c
DW
3570 nWidth = 0L;
3571 nHeight = 0L;
3572 if (pMenuItem->OnMeasureItem( &nWidth
3573 ,&nHeight
3574 ))
3575 {
f5ea767e
DW
3576 MRESULT mRc;
3577
4049cc1c
DW
3578 pMeasureStruct->rclItem.xRight = nWidth;
3579 pMeasureStruct->rclItem.xLeft = 0L;
3580 pMeasureStruct->rclItem.yTop = nHeight;
3581 pMeasureStruct->rclItem.yBottom = 0L;
f5ea767e
DW
3582 mRc = MRFROM2SHORT(nHeight, nWidth);
3583 return LONGFROMMR(mRc);
4049cc1c 3584 }
f5ea767e 3585 return 0L;
45bedfdd 3586 }
cdf1e714 3587 }
f15b4952 3588 wxWindow* pItem = FindItem(lId);
cdf1e714 3589
402e2f7c 3590 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
cdf1e714 3591 {
1de4baa3
DW
3592 OWNERITEM vItem;
3593
3594 vItem.idItem = (LONG)pItemStruct;
3595 return ((wxControl *)pItem)->OS2OnMeasure((WXMEASUREITEMSTRUCT*)&vItem);
cdf1e714 3596 }
19193a2c
KB
3597#else
3598 lId = lId;
3599 pItemStruct = pItemStruct;
3600#endif // wxUSE_OWNER_DRAWN
cdf1e714 3601 return FALSE;
0e320a79
DW
3602}
3603
cdf1e714
DW
3604// ---------------------------------------------------------------------------
3605// colours and palettes
3606// ---------------------------------------------------------------------------
849949b1 3607
0367c1c0 3608bool wxWindowOS2::HandleSysColorChange()
0e320a79 3609{
61243a51 3610 wxSysColourChangedEvent vEvent;
cdf1e714 3611
61243a51
DW
3612 vEvent.SetEventObject(this);
3613 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3614} // end of wxWindowOS2::HandleSysColorChange
0e320a79 3615
0367c1c0 3616bool wxWindowOS2::HandleCtlColor(
19193a2c 3617 WXHBRUSH* WXUNUSED(phBrush)
61243a51 3618)
0e320a79 3619{
61243a51
DW
3620 //
3621 // Not much provided with message. So not sure I can do anything with it
3622 //
3623 return TRUE;
0367c1c0 3624} // end of wxWindowOS2::HandleCtlColor
cdf1e714 3625
0e320a79 3626
cdf1e714 3627// Define for each class of dialog and control
19193a2c
KB
3628WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
3629 WXHWND WXUNUSED(hWnd),
3630 WXUINT WXUNUSED(nCtlColor),
3631 WXUINT WXUNUSED(message),
3632 WXWPARAM WXUNUSED(wParam),
3633 WXLPARAM WXUNUSED(lParam))
0e320a79 3634{
cdf1e714 3635 return (WXHBRUSH)0;
0e320a79
DW
3636}
3637
0367c1c0 3638bool wxWindowOS2::HandlePaletteChanged()
0e320a79 3639{
61243a51
DW
3640 // need to set this to something first
3641 WXHWND hWndPalChange = NULLHANDLE;
cdf1e714 3642
61243a51
DW
3643 wxPaletteChangedEvent vEvent(GetId());
3644
3645 vEvent.SetEventObject(this);
3646 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
0e320a79 3647
61243a51 3648 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3649} // end of wxWindowOS2::HandlePaletteChanged
61243a51 3650
61243a51 3651//
cdf1e714 3652// Responds to colour changes: passes event on to children.
61243a51 3653//
0367c1c0 3654void wxWindowOS2::OnSysColourChanged(
61243a51
DW
3655 wxSysColourChangedEvent& rEvent
3656)
0e320a79 3657{
2461cfa0 3658 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
61243a51 3659
2461cfa0 3660 while (node)
cdf1e714 3661 {
61243a51 3662 //
cdf1e714 3663 // Only propagate to non-top-level windows
61243a51 3664 //
2461cfa0 3665 wxWindow* pWin = (wxWindow *)node->GetData();
61243a51
DW
3666
3667 if (pWin->GetParent())
cdf1e714 3668 {
61243a51 3669 wxSysColourChangedEvent vEvent;
cdf1e714 3670
687706f5 3671 rEvent.SetEventObject(pWin);
61243a51
DW
3672 pWin->GetEventHandler()->ProcessEvent(vEvent);
3673 }
2461cfa0 3674 node = node->GetNext();
cdf1e714 3675 }
0367c1c0 3676} // end of wxWindowOS2::OnSysColourChanged
0e320a79 3677
cdf1e714
DW
3678// ---------------------------------------------------------------------------
3679// painting
3680// ---------------------------------------------------------------------------
3681
b45bca40
DW
3682void wxWindow::OnPaint (
3683 wxPaintEvent& rEvent
3684)
3685{
3686 HDC hDC = (HDC)wxPaintDC::FindDCInCache((wxWindow*) rEvent.GetEventObject());
3687
3688 if (hDC != 0)
3689 {
3690 OS2DefWindowProc( (WXUINT)WM_PAINT
3691 ,(WXWPARAM)hDC
3692 ,(WXLPARAM)0
3693 );
3694 }
3695} // end of wxWindow::OnPaint
3696
0367c1c0 3697bool wxWindowOS2::HandlePaint()
0e320a79 3698{
19193a2c
KB
3699 HRGN hRgn;
3700 wxPaintEvent vEvent(m_windowId);
40bd6154 3701 HPS hPS;
19193a2c
KB
3702 bool bProcessed;
3703
3704 // Create empty region
3705 // TODO: get HPS somewhere else if possible
3706 hPS = ::WinGetPS(GetHwnd());
3707 hRgn = ::GpiCreateRegion(hPS, 0, NULL);
61243a51 3708
19193a2c 3709 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
61243a51
DW
3710 {
3711 wxLogLastError("CreateRectRgn");
3712 return FALSE;
3713 }
7e99520b 3714
5d826f60
SN
3715 // Get all the rectangles from the region, convert the individual
3716 // rectangles to "the other" coordinate system and reassemble a
3717 // region from the rectangles, to be feed into m_updateRegion.
3718 //
3719 // FIXME: This is a bad hack since OS/2 API specifies that rectangles
3720 // passed into GpiSetRegion must not have Bottom > Top,
3721 // however, at first sight, it _seems_ to work nonetheless.
3722 //
3723 RGNRECT vRgnData;
3724 PRECTL pUpdateRects = NULL;
3725 vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
3726 if (::GpiQueryRegionRects( hPS // Pres space
3727 ,hRgn // Handle of region to query
3728 ,NULL // Return all RECTs
3729 ,&vRgnData // Will contain number or RECTs in region
3730 ,NULL // NULL to return number of RECTs
3731 ))
3732 {
3733 pUpdateRects = new RECTL[vRgnData.crcReturned];
3734 vRgnData.crc = vRgnData.crcReturned;
3735 vRgnData.ircStart = 1;
3736 if (::GpiQueryRegionRects( hPS // Pres space of source
3737 ,hRgn // Handle of source region
3738 ,NULL // Return all RECTs
3739 ,&vRgnData // Operations set to return rects
3740 ,pUpdateRects // Will contain the actual RECTS
3741 ))
3742 {
3743 int height;
3744 RECT vRect;
3745 ::WinQueryWindowRect(GetHwnd(), &vRect);
3746 height = vRect.yTop;
3747
3748 for(size_t i = 0; i < vRgnData.crc; i++)
3749 {
3750 int rectHeight;
3751 rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
3752 pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
3753 pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
3754 }
3755 ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
3756 delete [] pUpdateRects;
3757 }
3758 }
3759
19193a2c
KB
3760 m_updateRegion = wxRegion(hRgn, hPS);
3761
61243a51 3762 vEvent.SetEventObject(this);
19193a2c
KB
3763 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
3764
524d72c4
DW
3765 if (!bProcessed &&
3766 IsKindOf(CLASSINFO(wxPanel)) &&
3767 GetChildren().GetCount() == 0
3768 )
3769 {
3770 //
3771 // OS/2 needs to process this right here, not by the default proc
f289196b
DW
3772 // Window's default proc correctly paints everything, OS/2 does not.
3773 // For decorative panels that typically have no children, we draw
3774 // borders.
524d72c4
DW
3775 //
3776 HPS hPS;
3777 RECTL vRect;
524d72c4
DW
3778
3779 hPS = ::WinBeginPaint( GetHwnd()
3780 ,NULLHANDLE
3781 ,&vRect
3782 );
3783 if(hPS)
3784 {
3785 ::GpiCreateLogColorTable( hPS
3786 ,0L
3787 ,LCOLF_CONSECRGB
3788 ,0L
3789 ,(LONG)wxTheColourDatabase->m_nSize
3790 ,(PLONG)wxTheColourDatabase->m_palTable
3791 );
3792 ::GpiCreateLogColorTable( hPS
3793 ,0L
3794 ,LCOLF_RGB
3795 ,0L
3796 ,0L
3797 ,NULL
3798 );
1de4baa3 3799 if (::WinIsWindowVisible(GetHWND()))
f289196b 3800 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
1de4baa3
DW
3801 if (m_dwExStyle)
3802 {
3803 LINEBUNDLE vLineBundle;
3804
3805 vLineBundle.lColor = 0x00000000; // Black
3806 vLineBundle.usMixMode = FM_OVERPAINT;
3807 vLineBundle.fxWidth = 1;
3808 vLineBundle.lGeomWidth = 1;
3809 vLineBundle.usType = LINETYPE_SOLID;
3810 vLineBundle.usEnd = 0;
3811 vLineBundle.usJoin = 0;
3812 ::GpiSetAttrs( hPS
3813 ,PRIM_LINE
3814 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
3815 ,0L
3816 ,&vLineBundle
3817 );
3818 ::WinQueryWindowRect(GetHwnd(), &vRect);
3819 wxDrawBorder( hPS
3820 ,vRect
3821 ,m_dwExStyle
3822 );
524d72c4 3823 }
524d72c4 3824 }
f289196b 3825 ::WinEndPaint(hPS);
524d72c4
DW
3826 bProcessed = TRUE;
3827 }
f289196b
DW
3828 else if (!bProcessed &&
3829 IsKindOf(CLASSINFO(wxPanel))
3830 )
3831 {
3832 //
3833 // Panel with children, usually fills a frame client so no borders.
3834 //
3835 HPS hPS;
3836 RECTL vRect;
524d72c4 3837
f289196b
DW
3838 hPS = ::WinBeginPaint( GetHwnd()
3839 ,NULLHANDLE
3840 ,&vRect
3841 );
3842 if(hPS)
3843 {
3844 ::GpiCreateLogColorTable( hPS
3845 ,0L
3846 ,LCOLF_CONSECRGB
3847 ,0L
3848 ,(LONG)wxTheColourDatabase->m_nSize
3849 ,(PLONG)wxTheColourDatabase->m_palTable
3850 );
3851 ::GpiCreateLogColorTable( hPS
3852 ,0L
3853 ,LCOLF_RGB
3854 ,0L
3855 ,0L
3856 ,NULL
3857 );
3858
1de4baa3 3859 if (::WinIsWindowVisible(GetHWND()))
f289196b
DW
3860 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3861 }
3862 ::WinEndPaint(hPS);
3863 bProcessed = TRUE;
3864 }
524d72c4 3865 return bProcessed;
0367c1c0 3866} // end of wxWindowOS2::HandlePaint
0e320a79 3867
0367c1c0 3868bool wxWindowOS2::HandleEraseBkgnd(
8d854fa9
DW
3869 WXHDC hDC
3870)
0e320a79 3871{
8d854fa9 3872 SWP vSwp;
19193a2c 3873 bool rc;
8d854fa9
DW
3874
3875 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3876 if (vSwp.fl & SWP_MINIMIZE)
61243a51 3877 return TRUE;
cdf1e714 3878
8d854fa9
DW
3879 wxDC vDC;
3880
3881 vDC.m_hPS = (HPS)hDC; // this is really a PS
19193a2c 3882 vDC.SetWindow((wxWindow*)this);
8d854fa9 3883 vDC.BeginDrawing();
cdf1e714 3884
8d854fa9
DW
3885 wxEraseEvent vEvent(m_windowId, &vDC);
3886
3887 vEvent.SetEventObject(this);
cdf1e714 3888
19193a2c 3889 rc = GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3890
8d854fa9
DW
3891 vDC.EndDrawing();
3892 vDC.m_hPS = NULLHANDLE;
61243a51 3893 return TRUE;
0367c1c0 3894} // end of wxWindowOS2::HandleEraseBkgnd
cdf1e714 3895
0367c1c0 3896void wxWindowOS2::OnEraseBackground(
61243a51
DW
3897 wxEraseEvent& rEvent
3898)
0e320a79 3899{
8d854fa9
DW
3900 RECTL vRect;
3901 HPS hPS = rEvent.m_dc->m_hPS;
19193a2c
KB
3902 APIRET rc;
3903 LONG lColor = m_backgroundColour.GetPixel();
8d854fa9 3904
19193a2c
KB
3905 rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
3906 rc = ::WinFillRect(hPS, &vRect, lColor);
0367c1c0 3907} // end of wxWindowOS2::OnEraseBackground
0e320a79 3908
cdf1e714
DW
3909// ---------------------------------------------------------------------------
3910// moving and resizing
3911// ---------------------------------------------------------------------------
0e320a79 3912
0367c1c0 3913bool wxWindowOS2::HandleMinimize()
0e320a79 3914{
61243a51 3915 wxIconizeEvent vEvent(m_windowId);
cdf1e714 3916
61243a51
DW
3917 vEvent.SetEventObject(this);
3918 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3919} // end of wxWindowOS2::HandleMinimize
0e320a79 3920
0367c1c0 3921bool wxWindowOS2::HandleMaximize()
0e320a79 3922{
61243a51 3923 wxMaximizeEvent vEvent(m_windowId);
cdf1e714 3924
61243a51
DW
3925 vEvent.SetEventObject(this);
3926 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3927} // end of wxWindowOS2::HandleMaximize
0e320a79 3928
0367c1c0 3929bool wxWindowOS2::HandleMove(
61243a51
DW
3930 int nX
3931, int nY
3932)
0e320a79 3933{
19193a2c 3934 wxMoveEvent vEvent(wxPoint(nX, nY), m_windowId);
cdf1e714 3935
61243a51
DW
3936 vEvent.SetEventObject(this);
3937 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3938} // end of wxWindowOS2::HandleMove
0e320a79 3939
0367c1c0 3940bool wxWindowOS2::HandleSize(
61243a51
DW
3941 int nWidth
3942, int nHeight
3943, WXUINT WXUNUSED(nFlag)
3944)
0e320a79 3945{
19193a2c 3946 wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
cdf1e714 3947
61243a51
DW
3948 vEvent.SetEventObject(this);
3949 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3950} // end of wxWindowOS2::HandleSize
0e320a79 3951
0367c1c0 3952bool wxWindowOS2::HandleGetMinMaxInfo(
61243a51
DW
3953 PSWP pSwp
3954)
0e320a79 3955{
61243a51 3956 POINTL vPoint;
cdf1e714 3957
61243a51 3958 switch(pSwp->fl)
cdf1e714 3959 {
61243a51
DW
3960 case SWP_MAXIMIZE:
3961 ::WinGetMaxPosition(GetHwnd(), pSwp);
3962 m_maxWidth = pSwp->cx;
3963 m_maxHeight = pSwp->cy;
3964 break;
cdf1e714 3965
61243a51
DW
3966 case SWP_MINIMIZE:
3967 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3968 m_minWidth = pSwp->cx;
3969 m_minHeight = pSwp->cy;
3970 break;
cdf1e714 3971
61243a51
DW
3972 default:
3973 return FALSE;
cdf1e714 3974 }
61243a51 3975 return TRUE;
0367c1c0 3976} // end of wxWindowOS2::HandleGetMinMaxInfo
0e320a79 3977
cdf1e714
DW
3978// ---------------------------------------------------------------------------
3979// command messages
3980// ---------------------------------------------------------------------------
0367c1c0 3981bool wxWindowOS2::HandleCommand(
61243a51
DW
3982 WXWORD wId
3983, WXWORD wCmd
3984, WXHWND hControl
3985)
0e320a79 3986{
19193a2c 3987#if wxUSE_MENUS_NATIVE
61243a51 3988 if (wxCurrentPopupMenu)
0e320a79 3989 {
61243a51 3990 wxMenu* pPopupMenu = wxCurrentPopupMenu;
0e320a79 3991
61243a51
DW
3992 wxCurrentPopupMenu = NULL;
3993 return pPopupMenu->OS2Command(wCmd, wId);
cdf1e714 3994 }
19193a2c 3995#endif // wxUSE_MENUS_NATIVE
0e320a79 3996
61243a51
DW
3997 wxWindow* pWin = FindItem(wId);
3998
3999 if (!pWin)
cdf1e714 4000 {
61243a51 4001 pWin = wxFindWinFromHandle(hControl);
0e320a79 4002 }
cdf1e714 4003
61243a51 4004 if (pWin)
19193a2c
KB
4005 return pWin->OS2Command(wCmd, wId);
4006
cdf1e714 4007 return FALSE;
0367c1c0 4008} // end of wxWindowOS2::HandleCommand
de44a9f0 4009
0367c1c0 4010bool wxWindowOS2::HandleSysCommand(
61243a51 4011 WXWPARAM wParam
19193a2c 4012, WXLPARAM WXUNUSED(lParam)
61243a51 4013)
0e320a79 4014{
61243a51
DW
4015 //
4016 // 4 bits are reserved
4017 //
4018 switch (SHORT1FROMMP(wParam))
4019 {
4020 case SC_MAXIMIZE:
4021 return HandleMaximize();
4022
4023 case SC_MINIMIZE:
4024 return HandleMinimize();
4025 }
cdf1e714 4026 return FALSE;
0367c1c0 4027} // end of wxWindowOS2::HandleSysCommand
cdf1e714
DW
4028
4029// ---------------------------------------------------------------------------
4030// mouse events
4031// ---------------------------------------------------------------------------
19193a2c 4032//TODO!!! check against MSW
0367c1c0 4033void wxWindowOS2::InitMouseEvent(
61243a51
DW
4034 wxMouseEvent& rEvent
4035, int nX
4036, int nY
4037, WXUINT uFlags
4038)
cdf1e714 4039{
8d902dd6
SN
4040 int nHeight;
4041 DoGetSize(0, &nHeight);
61243a51 4042 rEvent.m_x = nX;
77ffb593 4043 // Convert to wxWidgets standard coordinate system!
8d902dd6
SN
4044 rEvent.m_y = nHeight - nY;
4045 rEvent.m_shiftDown = ((uFlags & KC_SHIFT) != 0);
4046 rEvent.m_controlDown = ((uFlags & KC_CTRL) != 0);
4047 rEvent.m_altDown = ((uFlags & KC_ALT) != 0);
4048 rEvent.m_leftDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
4049 0x8000) != 0;
4050 rEvent.m_middleDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &
4051 0x8000) != 0;
4052 rEvent.m_rightDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
4053 0x8000) != 0;
61243a51 4054 rEvent.SetTimestamp(s_currentMsg.time);
687706f5 4055 rEvent.SetEventObject(this);
6ed98c6a 4056 rEvent.SetId(GetId());
cdf1e714
DW
4057
4058#if wxUSE_MOUSEEVENT_HACK
61243a51
DW
4059 m_lastMouseX = nX;
4060 m_lastMouseY = nY;
4061 m_lastMouseEvent = rEvent.GetEventType();
cdf1e714 4062#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 4063} // end of wxWindowOS2::InitMouseEvent
0e320a79 4064
0367c1c0 4065bool wxWindowOS2::HandleMouseEvent(
61243a51
DW
4066 WXUINT uMsg
4067, int nX
4068, int nY
4069, WXUINT uFlags
4070)
0e320a79 4071{
b389a12d
DW
4072 bool bProcessed = FALSE;
4073
61243a51
DW
4074 //
4075 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
c82be69b 4076 // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
cdf1e714
DW
4077 // from the message id and take the value in the table to get wxWin event
4078 // id
61243a51 4079 //
cdf1e714
DW
4080 static const wxEventType eventsMouse[] =
4081 {
4082 wxEVT_MOTION,
4083 wxEVT_LEFT_DOWN,
4084 wxEVT_LEFT_UP,
4085 wxEVT_LEFT_DCLICK,
4086 wxEVT_RIGHT_DOWN,
4087 wxEVT_RIGHT_UP,
4088 wxEVT_RIGHT_DCLICK,
4089 wxEVT_MIDDLE_DOWN,
4090 wxEVT_MIDDLE_UP,
4091 wxEVT_MIDDLE_DCLICK
4092 };
4093
c82be69b
JS
4094 // Bounds check
4095 if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
b389a12d 4096 {
c82be69b 4097 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
b389a12d 4098
c82be69b
JS
4099 InitMouseEvent( vEvent
4100 ,nX
4101 ,nY
4102 ,uFlags
4103 );
4104
4105 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
4106 if (!bProcessed)
b389a12d 4107 {
c82be69b
JS
4108 HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
4109
4110 if (hCursor != NULLHANDLE)
4111 {
4112 ::WinSetPointer(HWND_DESKTOP, hCursor);
4113 bProcessed = TRUE;
4114 }
b389a12d
DW
4115 }
4116 }
c82be69b 4117 return bProcessed;
0367c1c0 4118} // end of wxWindowOS2::HandleMouseEvent
61243a51 4119
0367c1c0 4120bool wxWindowOS2::HandleMouseMove(
61243a51
DW
4121 int nX
4122, int nY
4123, WXUINT uFlags
4124)
0e320a79 4125{
61243a51 4126 if (!m_bMouseInWindow)
cdf1e714 4127 {
61243a51 4128 //
cdf1e714 4129 // Generate an ENTER event
61243a51 4130 //
776d87d5 4131 m_bMouseInWindow = TRUE;
cdf1e714 4132
61243a51 4133 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
cdf1e714 4134
61243a51
DW
4135 InitMouseEvent( vEvent
4136 ,nX
4137 ,nY
4138 ,uFlags
4139 );
cdf1e714 4140
61243a51 4141 (void)GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 4142 }
61243a51
DW
4143 return HandleMouseEvent( WM_MOUSEMOVE
4144 ,nX
4145 ,nY
4146 ,uFlags
4147 );
0367c1c0 4148} // end of wxWindowOS2::HandleMouseMove
0e320a79 4149
cdf1e714
DW
4150// ---------------------------------------------------------------------------
4151// keyboard handling
4152// ---------------------------------------------------------------------------
4153
61243a51
DW
4154//
4155// Create the key event of the given type for the given key - used by
4156// HandleChar and HandleKeyDown/Up
4157//
0367c1c0 4158wxKeyEvent wxWindowOS2::CreateKeyEvent(
61243a51
DW
4159 wxEventType eType
4160, int nId
4161, WXLPARAM lParam
a086de98 4162, WXWPARAM wParam
61243a51
DW
4163) const
4164{
4165 wxKeyEvent vEvent(eType);
4166
4167 vEvent.SetId(GetId());
4168 vEvent.m_shiftDown = IsShiftDown();
4169 vEvent.m_controlDown = IsCtrlDown();
4170 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
4171
687706f5 4172 vEvent.SetEventObject((wxWindow *)this); // const_cast
61243a51 4173 vEvent.m_keyCode = nId;
a086de98
DW
4174 vEvent.m_rawCode = (wxUint32)wParam;
4175 vEvent.m_rawFlags = (wxUint32)lParam;
61243a51
DW
4176 vEvent.SetTimestamp(s_currentMsg.time);
4177
4178 //
4179 // Translate the position to client coords
4180 //
4181 POINTL vPoint;
4182 RECTL vRect;
4183
4184 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
4185 ::WinQueryWindowRect( GetHwnd()
4186 ,&vRect
4187 );
4188
4189 vPoint.x -= vRect.xLeft;
4190 vPoint.y -= vRect.yBottom;
4191
4192 vEvent.m_x = vPoint.x;
4193 vEvent.m_y = vPoint.y;
4194
4195 return vEvent;
0367c1c0 4196} // end of wxWindowOS2::CreateKeyEvent
61243a51
DW
4197
4198//
cdf1e714
DW
4199// isASCII is TRUE only when we're called from WM_CHAR handler and not from
4200// WM_KEYDOWN one
61243a51 4201//
0367c1c0 4202bool wxWindowOS2::HandleChar(
598d8cac 4203 WXWPARAM wParam
61243a51
DW
4204, WXLPARAM lParam
4205, bool isASCII
4206)
86de7616 4207{
61243a51
DW
4208 bool bCtrlDown = FALSE;
4209 int vId;
4210
3437f881
DW
4211 if (m_bLastKeydownProcessed)
4212 {
4213 //
4214 // The key was handled in the EVT_KEY_DOWN. Handling a key in an
4215 // EVT_KEY_DOWN handler is meant, by design, to prevent EVT_CHARs
4216 // from happening, so just bail out at this point.
4217 //
4218 m_bLastKeydownProcessed = FALSE;
4219 return TRUE;
4220 }
61243a51
DW
4221 if (isASCII)
4222 {
4223 //
a23692f0
DW
4224 // If 1 -> 26, translate to either special keycode or just set
4225 // ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
4226 // ControlDown() == TRUE.
61243a51 4227 //
1de4baa3 4228 vId = SHORT1FROMMP(lParam);
61243a51
DW
4229 if ((vId > 0) && (vId < 27))
4230 {
4231 switch (vId)
4232 {
4233 case 13:
4234 vId = WXK_RETURN;
4235 break;
4236
4237 case 8:
4238 vId = WXK_BACK;
4239 break;
4240
4241 case 9:
4242 vId = WXK_TAB;
4243 break;
4244
4245 default:
4246 bCtrlDown = TRUE;
a23692f0 4247 break;
61243a51
DW
4248 }
4249 }
4250 }
a086de98 4251 else // we're called from WM_KEYDOWN
61243a51 4252 {
1de4baa3 4253 vId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
a086de98
DW
4254 if (vId == 0)
4255 return FALSE;
61243a51
DW
4256 }
4257
a086de98 4258 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
61243a51
DW
4259 ,vId
4260 ,lParam
4261 ));
4262
a086de98
DW
4263 if (bCtrlDown)
4264 {
4265 vEvent.m_controlDown = TRUE;
61243a51 4266 }
a086de98 4267 return (GetEventHandler()->ProcessEvent(vEvent));
cdf1e714 4268}
86de7616 4269
0367c1c0 4270bool wxWindowOS2::HandleKeyDown(
a086de98 4271 WXWPARAM wParam
61243a51
DW
4272, WXLPARAM lParam
4273)
cdf1e714 4274{
1de4baa3 4275 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
86de7616 4276
61243a51
DW
4277 if (!nId)
4278 {
4279 //
4280 // Normal ASCII char
4281 //
1de4baa3 4282 nId = SHORT1FROMMP(lParam);
61243a51
DW
4283 }
4284
4285 if (nId != -1)
4286 {
4287 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
4288 ,nId
a086de98
DW
4289 ,(MPARAM)lParam
4290 ,(MPARAM)wParam
61243a51
DW
4291 ));
4292
4293 if (GetEventHandler()->ProcessEvent(vEvent))
4294 {
4295 return TRUE;
4296 }
4297 }
4298 return FALSE;
0367c1c0 4299} // end of wxWindowOS2::HandleKeyDown
61243a51 4300
0367c1c0 4301bool wxWindowOS2::HandleKeyUp(
a086de98 4302 WXWPARAM wParam
61243a51
DW
4303, WXLPARAM lParam
4304)
86de7616 4305{
1de4baa3 4306 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
61243a51
DW
4307
4308 if (!nId)
4309 {
4310 //
4311 // Normal ASCII char
4312 //
a086de98 4313 nId = (int)wParam;
61243a51
DW
4314 }
4315
4316 if (nId != -1)
4317 {
4318 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
4319 ,nId
4320 ,lParam
a086de98 4321 ,wParam
61243a51
DW
4322 ));
4323
4324 if (GetEventHandler()->ProcessEvent(vEvent))
4325 return TRUE;
4326 }
4327 return FALSE;
0367c1c0 4328} // end of wxWindowOS2::HandleKeyUp
86de7616 4329
cdf1e714
DW
4330// ---------------------------------------------------------------------------
4331// joystick
4332// ---------------------------------------------------------------------------
86de7616 4333
cdf1e714
DW
4334// ---------------------------------------------------------------------------
4335// scrolling
4336// ---------------------------------------------------------------------------
4337
0367c1c0 4338bool wxWindowOS2::OS2OnScroll(
61243a51
DW
4339 int nOrientation
4340, WXWORD wParam
4341, WXWORD wPos
4342, WXHWND hControl
4343)
cdf1e714 4344{
61243a51 4345 if (hControl)
86de7616 4346 {
61243a51
DW
4347 wxWindow* pChild = wxFindWinFromHandle(hControl);
4348
4349 if (pChild )
4350 return pChild->OS2OnScroll( nOrientation
4351 ,wParam
4352 ,wPos
4353 ,hControl
4354 );
cdf1e714 4355 }
86de7616 4356
61243a51
DW
4357 wxScrollWinEvent vEvent;
4358
4359 vEvent.SetPosition(wPos);
4360 vEvent.SetOrientation(nOrientation);
687706f5 4361 vEvent.SetEventObject(this);
61243a51
DW
4362
4363 switch (wParam)
4364 {
4365 case SB_LINEUP:
687706f5 4366 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEUP);
61243a51
DW
4367 break;
4368
4369 case SB_LINEDOWN:
687706f5 4370 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
61243a51
DW
4371 break;
4372
4373 case SB_PAGEUP:
687706f5 4374 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
61243a51
DW
4375 break;
4376
4377 case SB_PAGEDOWN:
687706f5 4378 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
61243a51
DW
4379 break;
4380
4381 case SB_SLIDERPOSITION:
687706f5 4382 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBRELEASE);
61243a51
DW
4383 break;
4384
4385 case SB_SLIDERTRACK:
687706f5 4386 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBTRACK);
61243a51
DW
4387 break;
4388
4389 default:
4390 return FALSE;
4391 }
4392 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 4393} // end of wxWindowOS2::OS2OnScroll
86de7616 4394
d8a3f66c
DW
4395void wxWindowOS2::MoveChildren(
4396 int nDiff
4397)
4398{
5efff147
DW
4399 //
4400 // We want to handle top levels ourself, manually
4401 //
4402 if (!IsTopLevel() && GetAutoLayout())
d8a3f66c 4403 {
f289196b
DW
4404 Layout();
4405 }
4406 else
4407 {
4408 SWP vSwp;
d8a3f66c 4409
2461cfa0
SN
4410 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
4411 node;
4412 node = node->GetNext())
d8a3f66c 4413 {
2461cfa0 4414 wxWindow* pWin = node->GetData();
d8a3f66c 4415
f289196b
DW
4416 ::WinQueryWindowPos( GetHwndOf(pWin)
4417 ,&vSwp
4418 );
4419 if (pWin->IsKindOf(CLASSINFO(wxControl)))
4420 {
4421 wxControl* pCtrl;
4422
4423 //
4424 // Must deal with controls that have margins like ENTRYFIELD. The SWP
4425 // struct of such a control will have and origin offset from its intended
4426 // position by the width of the margins.
4427 //
4428 pCtrl = wxDynamicCast(pWin, wxControl);
4429 vSwp.y -= pCtrl->GetYComp();
4430 vSwp.x -= pCtrl->GetXComp();
4431 }
4432 ::WinSetWindowPos( GetHwndOf(pWin)
4433 ,HWND_TOP
4434 ,vSwp.x
4435 ,vSwp.y - nDiff
4436 ,vSwp.cx
4437 ,vSwp.cy
52df30cf 4438 ,SWP_MOVE
f289196b
DW
4439 );
4440 ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
4441 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
4442 {
4443 wxRadioBox* pRadioBox;
4444
4445 pRadioBox = wxDynamicCast(pWin, wxRadioBox);
4446 pRadioBox->AdjustButtons( (int)vSwp.x
4447 ,(int)vSwp.y - nDiff
4448 ,(int)vSwp.cx
4449 ,(int)vSwp.cy
4450 ,pRadioBox->GetSizeFlags()
4451 );
4452 }
4453 if (pWin->IsKindOf(CLASSINFO(wxSlider)))
4454 {
4455 wxSlider* pSlider;
4456
4457 pSlider = wxDynamicCast(pWin, wxSlider);
4458 pSlider->AdjustSubControls( (int)vSwp.x
4459 ,(int)vSwp.y - nDiff
4460 ,(int)vSwp.cx
4461 ,(int)vSwp.cy
4462 ,(int)pSlider->GetSizeFlags()
4463 );
4464 }
d8a3f66c
DW
4465 }
4466 }
4a46a5df 4467 Refresh();
d8a3f66c
DW
4468} // end of wxWindowOS2::MoveChildren
4469
4470//
4471// Getting the Y position for a window, like a control, is a real
4472// pain. There are three sitatuions we must deal with in determining
77ffb593 4473// the OS2 to wxWidgets Y coordinate.
d8a3f66c
DW
4474//
4475// 1) The controls are created in a dialog.
4476// This is the easiest since a dialog is created with its original
4477// size so the standard: Y = ParentHeight - (Y + ControlHeight);
4478//
4479// 2) The controls are direct children of a frame
4480// In this instance the controls are actually children of the Frame's
4481// client. During creation the frame's client resizes several times
4482// during creation of the status bar and toolbars. The CFrame class
4483// will take care of this using its AlterChildPos proc.
4484//
4485// 3) The controls are children of a panel, which in turn is a child of
4486// a frame.
859e65de
DW
4487// The panel may be one of many, in which case the same treatment
4488// as 1 applies. It may be the only child, though.
d8a3f66c
DW
4489// This is the nastiest case. A panel is created as the only child of
4490// the frame and as such, when a frame has only one child, the child is
4491// expanded to fit the entire client area of the frame. Because the
4492// controls are created BEFORE this occurs their positions are totally
4493// whacked and any call to WinQueryWindowPos will return invalid
4494// coordinates. So for this situation we have to compare the size of
4495// the panel at control creation time with that of the frame client. If
4496// they are the same we can use the standard Y position equation. If
4497// not, then we must use the Frame Client's dimensions to position them
4498// as that will be the eventual size of the panel after the frame resizes
4499// it!
4500//
4501int wxWindowOS2::GetOS2ParentHeight(
4502 wxWindowOS2* pParent
4503)
4504{
d8a3f66c
DW
4505 //
4506 // Case 1
4507 //
4508 if (pParent->IsKindOf(CLASSINFO(wxDialog)))
e37db699 4509 return(pParent->GetClientSize().y);
d8a3f66c
DW
4510
4511 //
4512 // Case 2 -- if we are one of the separately built standard Frame
4513 // children, like a statusbar, menubar, or toolbar we want to
4514 // use the frame, itself, for positioning. Otherwise we are
4515 // child window and want to use the Frame's client.
4516 //
4517 else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
4518 {
4519 if (IsKindOf(CLASSINFO(wxStatusBar)) ||
4520 IsKindOf(CLASSINFO(wxMenuBar)) ||
4521 IsKindOf(CLASSINFO(wxToolBar))
4522 )
2590f154
DW
4523 {
4524 if (IsKindOf(CLASSINFO(wxToolBar)))
4525 {
4526 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
4527
4528 if (pFrame->GetToolBar() == this)
4529 return(pParent->GetSize().y);
4530 else
4531 return(pParent->GetClientSize().y);
4532 }
4533 else
4534 return(pParent->GetSize().y);
4535 }
d8a3f66c
DW
4536 else
4537 return(pParent->GetClientSize().y);
4538 }
d8a3f66c 4539 //
4a46a5df
DW
4540 // Case -- this is for any window that is the sole child of a Frame.
4541 // The grandparent must exist and it must be of type CFrame
4542 // and it's height must be different. Otherwise the standard
4543 // applies.
d8a3f66c
DW
4544 //
4545 else
4546 {
4a46a5df 4547 return(pParent->GetClientSize().y);
d8a3f66c
DW
4548 }
4549 return(0L);
4550} // end of wxWindowOS2::GetOS2ParentHeight
4551
45e0dc94
DW
4552//
4553// OS/2 needs a lot extra manipulation to deal with layouts
4554// for canvas windows, particularly scrolled ones.
4555//
06519806
DW
4556wxWindowCreationHook::wxWindowCreationHook(
4557 wxWindow* pWinBeingCreated
4558)
4559{
4560 gpWinBeingCreated = pWinBeingCreated;
4561} // end of wxWindowCreationHook::wxWindowCreationHook
4562
4563wxWindowCreationHook::~wxWindowCreationHook()
4564{
4565 gpWinBeingCreated = NULL;
4566} // end of wxWindowCreationHook::~wxWindowCreationHook
4567
cdf1e714
DW
4568// ===========================================================================
4569// global functions
4570// ===========================================================================
4571
61243a51 4572void wxGetCharSize(
987da0d4
DW
4573 WXHWND hWnd
4574, int* pX
4575, int* pY
19193a2c 4576,wxFont* WXUNUSED(pTheFont)
61243a51 4577)
cdf1e714 4578{
987da0d4
DW
4579 FONTMETRICS vFM;
4580 HPS hPS;
4581 BOOL rc;
4582
4583 hPS =::WinGetPS(hWnd);
4584
4585 rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
4586 if (rc)
4587 {
4588 if (pX)
4589 *pX = vFM.lAveCharWidth;
4590 if (pY)
4591 *pY = vFM.lEmHeight + vFM.lExternalLeading;
4592 }
4593 else
4594 {
4595 if (pX)
4596 *pX = 10;
4597 if (pY)
4598 *pY = 15;
4599 }
4600 ::WinReleasePS(hPS);
61243a51 4601} // end of wxGetCharSize
cdf1e714 4602
61243a51 4603//
cdf1e714
DW
4604// Returns 0 if was a normal ASCII value, not a special key. This indicates that
4605// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
61243a51
DW
4606//
4607int wxCharCodeOS2ToWX(
4608 int nKeySym
4609)
cdf1e714 4610{
61243a51
DW
4611 int nId = 0;
4612
4613 switch (nKeySym)
4614 {
4615 case VK_BACKTAB: nId = WXK_BACK; break;
4616 case VK_TAB: nId = WXK_TAB; break;
4617 case VK_CLEAR: nId = WXK_CLEAR; break;
4618 case VK_ENTER: nId = WXK_RETURN; break;
4619 case VK_SHIFT: nId = WXK_SHIFT; break;
4620 case VK_CTRL: nId = WXK_CONTROL; break;
4621 case VK_PAUSE: nId = WXK_PAUSE; break;
4622 case VK_SPACE: nId = WXK_SPACE; break;
4623 case VK_ESC: nId = WXK_ESCAPE; break;
4624 case VK_END: nId = WXK_END; break;
4625 case VK_HOME : nId = WXK_HOME; break;
4626 case VK_LEFT : nId = WXK_LEFT; break;
4627 case VK_UP: nId = WXK_UP; break;
4628 case VK_RIGHT: nId = WXK_RIGHT; break;
4629 case VK_DOWN : nId = WXK_DOWN; break;
4630 case VK_PRINTSCRN: nId = WXK_PRINT; break;
4631 case VK_INSERT: nId = WXK_INSERT; break;
4632 case VK_DELETE: nId = WXK_DELETE; break;
a086de98 4633 case VK_CAPSLOCK: nId = WXK_CAPITAL; break;
61243a51
DW
4634 case VK_F1: nId = WXK_F1; break;
4635 case VK_F2: nId = WXK_F2; break;
4636 case VK_F3: nId = WXK_F3; break;
4637 case VK_F4: nId = WXK_F4; break;
4638 case VK_F5: nId = WXK_F5; break;
4639 case VK_F6: nId = WXK_F6; break;
4640 case VK_F7: nId = WXK_F7; break;
4641 case VK_F8: nId = WXK_F8; break;
4642 case VK_F9: nId = WXK_F9; break;
4643 case VK_F10: nId = WXK_F10; break;
4644 case VK_F11: nId = WXK_F11; break;
4645 case VK_F12: nId = WXK_F12; break;
4646 case VK_F13: nId = WXK_F13; break;
4647 case VK_F14: nId = WXK_F14; break;
4648 case VK_F15: nId = WXK_F15; break;
4649 case VK_F16: nId = WXK_F16; break;
4650 case VK_F17: nId = WXK_F17; break;
4651 case VK_F18: nId = WXK_F18; break;
4652 case VK_F19: nId = WXK_F19; break;
4653 case VK_F20: nId = WXK_F20; break;
4654 case VK_F21: nId = WXK_F21; break;
4655 case VK_F22: nId = WXK_F22; break;
4656 case VK_F23: nId = WXK_F23; break;
4657 case VK_F24: nId = WXK_F24; break;
a086de98
DW
4658 case VK_OEM_1: nId = ';'; break;
4659 case VK_OEM_PLUS: nId = '+'; break;
4660 case VK_OEM_COMMA: nId = ','; break;
4661 case VK_OEM_MINUS: nId = '-'; break;
4662 case VK_OEM_PERIOD: nId = '.'; break;
4663 case VK_OEM_2: nId = '/'; break;
4664 case VK_OEM_3: nId = '~'; break;
4665 case VK_OEM_4: nId = '['; break;
4666 case VK_OEM_5: nId = '\\'; break;
4667 case VK_OEM_6: nId = ']'; break;
4668 case VK_OEM_7: nId = '\''; break;
61243a51
DW
4669 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
4670 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
4671 default:
86de7616 4672 {
cdf1e714 4673 return 0;
86de7616
DW
4674 }
4675 }
61243a51
DW
4676 return nId;
4677} // end of wxCharCodeOS2ToWX
86de7616 4678
61243a51
DW
4679int wxCharCodeWXToOS2(
4680 int nId
4681, bool* bIsVirtual
4682)
86de7616 4683{
61243a51
DW
4684 int nKeySym = 0;
4685
4686 *bIsVirtual = TRUE;
4687 switch (nId)
4688 {
4689 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
4690 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
4691 case WXK_CONTROL: nKeySym = VK_CTRL; break;
4692 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
4693 case WXK_END: nKeySym = VK_END; break;
4694 case WXK_HOME : nKeySym = VK_HOME; break;
4695 case WXK_LEFT : nKeySym = VK_LEFT; break;
4696 case WXK_UP: nKeySym = VK_UP; break;
4697 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
4698 case WXK_DOWN : nKeySym = VK_DOWN; break;
4699 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
4700 case WXK_INSERT: nKeySym = VK_INSERT; break;
4701 case WXK_DELETE: nKeySym = VK_DELETE; break;
4702 case WXK_F1: nKeySym = VK_F1; break;
4703 case WXK_F2: nKeySym = VK_F2; break;
4704 case WXK_F3: nKeySym = VK_F3; break;
4705 case WXK_F4: nKeySym = VK_F4; break;
4706 case WXK_F5: nKeySym = VK_F5; break;
4707 case WXK_F6: nKeySym = VK_F6; break;
4708 case WXK_F7: nKeySym = VK_F7; break;
4709 case WXK_F8: nKeySym = VK_F8; break;
4710 case WXK_F9: nKeySym = VK_F9; break;
4711 case WXK_F10: nKeySym = VK_F10; break;
4712 case WXK_F11: nKeySym = VK_F11; break;
4713 case WXK_F12: nKeySym = VK_F12; break;
4714 case WXK_F13: nKeySym = VK_F13; break;
4715 case WXK_F14: nKeySym = VK_F14; break;
4716 case WXK_F15: nKeySym = VK_F15; break;
4717 case WXK_F16: nKeySym = VK_F16; break;
4718 case WXK_F17: nKeySym = VK_F17; break;
4719 case WXK_F18: nKeySym = VK_F18; break;
4720 case WXK_F19: nKeySym = VK_F19; break;
4721 case WXK_F20: nKeySym = VK_F20; break;
4722 case WXK_F21: nKeySym = VK_F21; break;
4723 case WXK_F22: nKeySym = VK_F22; break;
4724 case WXK_F23: nKeySym = VK_F23; break;
4725 case WXK_F24: nKeySym = VK_F24; break;
4726 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
4727 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
4728 default:
cdf1e714 4729 {
61243a51
DW
4730 *bIsVirtual = FALSE;
4731 nKeySym = nId;
cdf1e714
DW
4732 break;
4733 }
86de7616 4734 }
61243a51
DW
4735 return nKeySym;
4736} // end of wxCharCodeWXToOS2
86de7616 4737
61243a51 4738wxWindow* wxGetActiveWindow()
cdf1e714 4739{
61243a51 4740 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
86de7616 4741
61243a51
DW
4742 if (hWnd != 0)
4743 {
4744 return wxFindWinFromHandle((WXHWND)hWnd);
4745 }
4746 return NULL;
4747} // end of wxGetActiveWindow
cdf1e714
DW
4748
4749#ifdef __WXDEBUG__
61243a51
DW
4750const char* wxGetMessageName(
4751 int nMessage)
cdf1e714 4752{
61243a51 4753 switch (nMessage)
86de7616 4754 {
cdf1e714
DW
4755 case 0x0000: return "WM_NULL";
4756 case 0x0001: return "WM_CREATE";
4757 case 0x0002: return "WM_DESTROY";
61243a51
DW
4758 case 0x0004: return "WM_ENABLE";
4759 case 0x0005: return "WM_SHOW";
4760 case 0x0006: return "WM_MOVE";
4761 case 0x0007: return "WM_SIZE";
4762 case 0x0008: return "WM_ADJUSTWINDOWPOS";
4763 case 0x0009: return "WM_CALCVALIDRECTS";
4764 case 0x000A: return "WM_SETWINDOWPARAMS";
4765 case 0x000B: return "WM_QUERYWINDOWPARAMS";
4766 case 0x000C: return "WM_HITTEST";
4767 case 0x000D: return "WM_ACTIVATE";
4768 case 0x000F: return "WM_SETFOCUS";
4769 case 0x0010: return "WM_SETSELECTION";
4770 case 0x0011: return "WM_PPAINT";
4771 case 0x0012: return "WM_PSETFOCUS";
4772 case 0x0013: return "WM_PSYSCOLORCHANGE";
4773 case 0x0014: return "WM_PSIZE";
4774 case 0x0015: return "WM_PACTIVATE";
4775 case 0x0016: return "WM_PCONTROL";
4776 case 0x0020: return "WM_COMMAND";
4777 case 0x0021: return "WM_SYSCOMMAND";
4778 case 0x0022: return "WM_HELP";
4779 case 0x0023: return "WM_PAINT";
4780 case 0x0024: return "WM_TIMER";
4781 case 0x0025: return "WM_SEM1";
4782 case 0x0026: return "WM_SEM2";
4783 case 0x0027: return "WM_SEM3";
4784 case 0x0028: return "WM_SEM4";
4785 case 0x0029: return "WM_CLOSE";
4786 case 0x002A: return "WM_QUIT";
4787 case 0x002B: return "WM_SYSCOLORCHANGE";
4788 case 0x002D: return "WM_SYSVALUECHANGE";
4789 case 0x002E: return "WM_APPTERMINATENOTIFY";
4790 case 0x002F: return "WM_PRESPARAMCHANGED";
4791 // Control notification messages
4792 case 0x0030: return "WM_CONTROL";
4793 case 0x0031: return "WM_VSCROLL";
4794 case 0x0032: return "WM_HSCROLL";
4795 case 0x0033: return "WM_INITMENU";
4796 case 0x0034: return "WM_MENUSELECT";
4797 case 0x0035: return "WM_MENUSEND";
4798 case 0x0036: return "WM_DRAWITEM";
4799 case 0x0037: return "WM_MEASUREITEM";
4800 case 0x0038: return "WM_CONTROLPOINTER";
4801 case 0x003A: return "WM_QUERYDLGCODE";
4802 case 0x003B: return "WM_INITDLG";
4803 case 0x003C: return "WM_SUBSTITUTESTRING";
4804 case 0x003D: return "WM_MATCHMNEMONIC";
4805 case 0x003E: return "WM_SAVEAPPLICATION";
4806 case 0x0129: return "WM_CTLCOLORCHANGE";
4807 case 0x0130: return "WM_QUERYCTLTYPE";
4808 // Frame messages
4809 case 0x0040: return "WM_FLASHWINDOW";
4810 case 0x0041: return "WM_FORMATFRAME";
4811 case 0x0042: return "WM_UPDATEFRAME";
4812 case 0x0043: return "WM_FOCUSCHANGE";
4813 case 0x0044: return "WM_SETBORDERSIZE";
4814 case 0x0045: return "WM_TRACKFRAME";
4815 case 0x0046: return "WM_MINMAXFRAME";
4816 case 0x0047: return "WM_SETICON";
4817 case 0x0048: return "WM_QUERYICON";
4818 case 0x0049: return "WM_SETACCELTABLE";
4819 case 0x004A: return "WM_QUERYACCELTABLE";
4820 case 0x004B: return "WM_TRANSLATEACCEL";
4821 case 0x004C: return "WM_QUERYTRACKINFO";
4822 case 0x004D: return "WM_QUERYBORDERSIZE";
4823 case 0x004E: return "WM_NEXTMENU";
4824 case 0x004F: return "WM_ERASEBACKGROUND";
4825 case 0x0050: return "WM_QUERYFRAMEINFO";
4826 case 0x0051: return "WM_QUERYFOCUSCHAIN";
4827 case 0x0052: return "WM_OWNERPOSCHANGE";
4828 case 0x0053: return "WM_CACLFRAMERECT";
4829 case 0x0055: return "WM_WINDOWPOSCHANGED";
4830 case 0x0056: return "WM_ADJUSTFRAMEPOS";
4831 case 0x0059: return "WM_QUERYFRAMECTLCOUNT";
4832 case 0x005B: return "WM_QUERYHELPINFO";
4833 case 0x005C: return "WM_SETHELPINFO";
4834 case 0x005D: return "WM_ERROR";
4835 case 0x005E: return "WM_REALIZEPALETTE";
4836 // Clipboard messages
4837 case 0x0060: return "WM_RENDERFMT";
4838 case 0x0061: return "WM_RENDERALLFMTS";
4839 case 0x0062: return "WM_DESTROYCLIPBOARD";
4840 case 0x0063: return "WM_PAINTCLIPBOARD";
4841 case 0x0064: return "WM_SIZECLIPBOARD";
4842 case 0x0065: return "WM_HSCROLLCLIPBOARD";
4843 case 0x0066: return "WM_VSCROLLCLIPBOARD";
4844 case 0x0067: return "WM_DRAWCLIPBOARD";
4845 // mouse messages
4846 case 0x0070: return "WM_MOUSEMOVE";
4847 case 0x0071: return "WM_BUTTON1DOWN";
4848 case 0x0072: return "WM_BUTTON1UP";
4849 case 0x0073: return "WM_BUTTON1DBLCLK";
4850 case 0x0074: return "WM_BUTTON2DOWN";
4851 case 0x0075: return "WM_BUTTON2UP";
4852 case 0x0076: return "WM_BUTTON2DBLCLK";
4853 case 0x0077: return "WM_BUTTON3DOWN";
4854 case 0x0078: return "WM_BUTTON3UP";
4855 case 0x0079: return "WM_BUTTON3DBLCLK";
4856 case 0x007D: return "WM_MOUSEMAP";
4857 case 0x007E: return "WM_VRNDISABLED";
4858 case 0x007F: return "WM_VRNENABLED";
4859 case 0x0410: return "WM_CHORD";
4860 case 0x0411: return "WM_BUTTON1MOTIONSTART";
4861 case 0x0412: return "WM_BUTTON1MOTIONEND";
4862 case 0x0413: return "WM_BUTTON1CLICK";
4863 case 0x0414: return "WM_BUTTON2MOTIONSTART";
4864 case 0x0415: return "WM_BUTTON2MOTIONEND";
4865 case 0x0416: return "WM_BUTTON2CLICK";
4866 case 0x0417: return "WM_BUTTON3MOTIONSTART";
4867 case 0x0418: return "WM_BUTTON3MOTIONEND";
4868 case 0x0419: return "WM_BUTTON3CLICK";
4869 case 0x0420: return "WM_BEGINDRAG";
4870 case 0x0421: return "WM_ENDDRAG";
4871 case 0x0422: return "WM_SINGLESELECT";
4872 case 0x0423: return "WM_OPEN";
4873 case 0x0424: return "WM_CONTEXTMENU";
4874 case 0x0425: return "WM_CONTEXTHELP";
4875 case 0x0426: return "WM_TEXTEDIT";
4876 case 0x0427: return "WM_BEGINSELECT";
4877 case 0x0228: return "WM_ENDSELECT";
4878 case 0x0429: return "WM_PICKUP";
4879 case 0x04C0: return "WM_PENFIRST";
4880 case 0x04FF: return "WM_PENLAST";
4881 case 0x0500: return "WM_MMPMFIRST";
4882 case 0x05FF: return "WM_MMPMLAST";
4883 case 0x0600: return "WM_STDDLGFIRST";
4884 case 0x06FF: return "WM_STDDLGLAST";
4885 case 0x0BD0: return "WM_BIDI_FIRST";
4886 case 0x0BFF: return "WM_BIDI_LAST";
4887 // keyboard input
4888 case 0x007A: return "WM_CHAR";
4889 case 0x007B: return "WM_VIOCHAR";
4890 // DDE messages
4891 case 0x00A0: return "WM_DDE_INITIATE";
4892 case 0x00A1: return "WM_DDE_REQUEST";
4893 case 0x00A2: return "WM_DDE_ACK";
4894 case 0x00A3: return "WM_DDE_DATA";
4895 case 0x00A4: return "WM_DDE_ADVISE";
4896 case 0x00A5: return "WM_DDE_UNADVISE";
4897 case 0x00A6: return "WM_DDE_POKE";
4898 case 0x00A7: return "WM_DDE_EXECUTE";
4899 case 0x00A8: return "WM_DDE_TERMINATE";
4900 case 0x00A9: return "WM_DDE_INITIATEACK";
4901 case 0x00AF: return "WM_DDE_LAST";
4902 // Buttons
4903 case 0x0120: return "BM_CLICK";
4904 case 0x0121: return "BM_QUERYCHECKINDEX";
4905 case 0x0122: return "BM_QUERYHILITE";
4906 case 0x0123: return "BM_SETHILITE";
4907 case 0x0124: return "BM_QUERYCHECK";
4908 case 0x0125: return "BM_SETCHECK";
4909 case 0x0126: return "BM_SETDEFAULT";
4910 case 0x0128: return "BM_AUTOSIZE";
4911 // Combo boxes
4912 case 0x029A: return "CBID_LIST";
4913 case 0x029B: return "CBID_EDIT";
4914 case 0x0170: return "CBM_SHOWLIST";
4915 case 0x0171: return "CBM_HILITE";
4916 case 0x0172: return "CBM_ISLISTSHOWING";
4917 // Edit fields
4918 case 0x0140: return "EM_QUERYCHANGED";
4919 case 0x0141: return "EM_QUERYSEL";
4920 case 0x0142: return "EM_SETSEL";
4921 case 0x0143: return "EM_SETTEXTLIMIT";
4922 case 0x0144: return "EM_CUT";
4923 case 0x0145: return "EM_COPY";
4924 case 0x0146: return "EM_CLEAR";
4925 case 0x0147: return "EM_PASTE";
4926 case 0x0148: return "EM_QUERYFIRSTCHAR";
4927 case 0x0149: return "EM_SETFIRSTCHAR";
4928 case 0x014A: return "EM_QUERYREADONLY";
4929 case 0x014B: return "EM_SETREADONLY";
4930 case 0x014C: return "EM_SETINSERTMODE";
4931 // Listboxes
4932 case 0x0160: return "LM_QUERYITEMCOUNT";
4933 case 0x0161: return "LM_INSERTITEM";
4934 case 0x0162: return "LM_SETOPENINDEX";
4935 case 0x0163: return "LM_DELETEITEM";
4936 case 0x0164: return "LM_SELECTITEM";
4937 case 0x0165: return "LM_QUERYSELECTION";
4938 case 0x0166: return "LM_SETITEMTEXT";
4939 case 0x0167: return "LM_QUERYITEMTEXTLENGTH";
4940 case 0x0168: return "LM_QUERYITEMTEXT";
4941 case 0x0169: return "LM_SETITEMHANDLE";
4942 case 0x016A: return "LM_QUERYITEMHANDLE";
4943 case 0x016B: return "LM_SEARCHSTRING";
4944 case 0x016C: return "LM_SETITEMHEIGHT";
4945 case 0x016D: return "LM_QUERYTOPINDEX";
4946 case 0x016E: return "LM_DELETEALL";
4947 case 0x016F: return "LM_INSERTMULITEMS";
4948 case 0x0660: return "LM_SETITEMWIDTH";
4949 // Menus
4950 case 0x0180: return "MM_INSERTITEM";
4951 case 0x0181: return "MM_DELETEITEM";
4952 case 0x0182: return "MM_QUERYITEM";
4953 case 0x0183: return "MM_SETITEM";
4954 case 0x0184: return "MM_QUERYITEMCOUNT";
4955 case 0x0185: return "MM_STARTMENUMODE";
4956 case 0x0186: return "MM_ENDMENUMODE";
4957 case 0x0188: return "MM_REMOVEITEM";
4958 case 0x0189: return "MM_SELECTITEM";
4959 case 0x018A: return "MM_QUERYSELITEMID";
4960 case 0x018B: return "MM_QUERYITEMTEXT";
4961 case 0x018C: return "MM_QUERYITEMTEXTLENGTH";
4962 case 0x018D: return "MM_SETITEMHANDLE";
4963 case 0x018E: return "MM_SETITEMTEXT";
4964 case 0x018F: return "MM_ITEMPOSITIONFROMID";
4965 case 0x0190: return "MM_ITEMIDFROMPOSITION";
4966 case 0x0191: return "MM_QUERYITEMATTR";
4967 case 0x0192: return "MM_SETITEMATTR";
4968 case 0x0193: return "MM_ISITEMVALID";
4969 case 0x0194: return "MM_QUERYITEMRECT";
4970 case 0x0431: return "MM_QUERYDEFAULTITEMID";
4971 case 0x0432: return "MM_SETDEFAULTITEMID";
4972 // Scrollbars
4973 case 0x01A0: return "SBM_SETSCROLLBAR";
4974 case 0x01A1: return "SBM_SETPOS";
4975 case 0x01A2: return "SBM_QUERYPOS";
4976 case 0x01A3: return "SBM_QUERYRANGE";
4977 case 0x01A6: return "SBM_SETTHUMBSIZE";
4978
4979 // Help messages
4980 case 0x0F00: return "WM_HELPBASE";
4981 case 0x0FFF: return "WM_HELPTOP";
4982 // Beginning of user defined messages
4983 case 0x1000: return "WM_USER";
4984
77ffb593 4985 // wxWidgets user defined types
cdf1e714
DW
4986
4987 // listview
61243a51 4988 // case 0x1000 + 0: return "LVM_GETBKCOLOR";
cdf1e714
DW
4989 case 0x1000 + 1: return "LVM_SETBKCOLOR";
4990 case 0x1000 + 2: return "LVM_GETIMAGELIST";
4991 case 0x1000 + 3: return "LVM_SETIMAGELIST";
4992 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
4993 case 0x1000 + 5: return "LVM_GETITEMA";
4994 case 0x1000 + 75: return "LVM_GETITEMW";
4995 case 0x1000 + 6: return "LVM_SETITEMA";
4996 case 0x1000 + 76: return "LVM_SETITEMW";
4997 case 0x1000 + 7: return "LVM_INSERTITEMA";
4998 case 0x1000 + 77: return "LVM_INSERTITEMW";
4999 case 0x1000 + 8: return "LVM_DELETEITEM";
5000 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
5001 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
5002 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
5003 case 0x1000 + 12: return "LVM_GETNEXTITEM";
5004 case 0x1000 + 13: return "LVM_FINDITEMA";
5005 case 0x1000 + 83: return "LVM_FINDITEMW";
5006 case 0x1000 + 14: return "LVM_GETITEMRECT";
5007 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
5008 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
5009 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
5010 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
5011 case 0x1000 + 18: return "LVM_HITTEST";
5012 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
5013 case 0x1000 + 20: return "LVM_SCROLL";
5014 case 0x1000 + 21: return "LVM_REDRAWITEMS";
5015 case 0x1000 + 22: return "LVM_ARRANGE";
5016 case 0x1000 + 23: return "LVM_EDITLABELA";
5017 case 0x1000 + 118: return "LVM_EDITLABELW";
5018 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
5019 case 0x1000 + 25: return "LVM_GETCOLUMNA";
5020 case 0x1000 + 95: return "LVM_GETCOLUMNW";
5021 case 0x1000 + 26: return "LVM_SETCOLUMNA";
5022 case 0x1000 + 96: return "LVM_SETCOLUMNW";
5023 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
5024 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
5025 case 0x1000 + 28: return "LVM_DELETECOLUMN";
5026 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
5027 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
5028 case 0x1000 + 31: return "LVM_GETHEADER";
5029 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
5030 case 0x1000 + 34: return "LVM_GETVIEWRECT";
5031 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
5032 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
5033 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
5034 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
5035 case 0x1000 + 39: return "LVM_GETTOPINDEX";
5036 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
5037 case 0x1000 + 41: return "LVM_GETORIGIN";
5038 case 0x1000 + 42: return "LVM_UPDATE";
5039 case 0x1000 + 43: return "LVM_SETITEMSTATE";
5040 case 0x1000 + 44: return "LVM_GETITEMSTATE";
5041 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
5042 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
5043 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
5044 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
5045 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
5046 case 0x1000 + 48: return "LVM_SORTITEMS";
5047 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
5048 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
5049 case 0x1000 + 51: return "LVM_GETITEMSPACING";
5050 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
5051 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
5052 case 0x1000 + 53: return "LVM_SETICONSPACING";
5053 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
5054 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
5055 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
5056 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
5057 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
5058 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
5059 case 0x1000 + 60: return "LVM_SETHOTITEM";
5060 case 0x1000 + 61: return "LVM_GETHOTITEM";
5061 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
5062 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
5063 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
5064 case 0x1000 + 65: return "LVM_SETWORKAREA";
5065
5066 // tree view
5067 case 0x1100 + 0: return "TVM_INSERTITEMA";
5068 case 0x1100 + 50: return "TVM_INSERTITEMW";
5069 case 0x1100 + 1: return "TVM_DELETEITEM";
5070 case 0x1100 + 2: return "TVM_EXPAND";
5071 case 0x1100 + 4: return "TVM_GETITEMRECT";
5072 case 0x1100 + 5: return "TVM_GETCOUNT";
5073 case 0x1100 + 6: return "TVM_GETINDENT";
5074 case 0x1100 + 7: return "TVM_SETINDENT";
5075 case 0x1100 + 8: return "TVM_GETIMAGELIST";
5076 case 0x1100 + 9: return "TVM_SETIMAGELIST";
5077 case 0x1100 + 10: return "TVM_GETNEXTITEM";
5078 case 0x1100 + 11: return "TVM_SELECTITEM";
5079 case 0x1100 + 12: return "TVM_GETITEMA";
5080 case 0x1100 + 62: return "TVM_GETITEMW";
5081 case 0x1100 + 13: return "TVM_SETITEMA";
5082 case 0x1100 + 63: return "TVM_SETITEMW";
5083 case 0x1100 + 14: return "TVM_EDITLABELA";
5084 case 0x1100 + 65: return "TVM_EDITLABELW";
5085 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
5086 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
5087 case 0x1100 + 17: return "TVM_HITTEST";
5088 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
5089 case 0x1100 + 19: return "TVM_SORTCHILDREN";
5090 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
5091 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
5092 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
5093 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
5094 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
5095 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
5096 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
5097
5098 // header
5099 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
5100 case 0x1200 + 1: return "HDM_INSERTITEMA";
5101 case 0x1200 + 10: return "HDM_INSERTITEMW";
5102 case 0x1200 + 2: return "HDM_DELETEITEM";
5103 case 0x1200 + 3: return "HDM_GETITEMA";
5104 case 0x1200 + 11: return "HDM_GETITEMW";
5105 case 0x1200 + 4: return "HDM_SETITEMA";
5106 case 0x1200 + 12: return "HDM_SETITEMW";
5107 case 0x1200 + 5: return "HDM_LAYOUT";
5108 case 0x1200 + 6: return "HDM_HITTEST";
5109 case 0x1200 + 7: return "HDM_GETITEMRECT";
5110 case 0x1200 + 8: return "HDM_SETIMAGELIST";
5111 case 0x1200 + 9: return "HDM_GETIMAGELIST";
5112 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
5113 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
5114 case 0x1200 + 17: return "HDM_GETORDERARRAY";
5115 case 0x1200 + 18: return "HDM_SETORDERARRAY";
5116 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
5117
5118 // tab control
5119 case 0x1300 + 2: return "TCM_GETIMAGELIST";
5120 case 0x1300 + 3: return "TCM_SETIMAGELIST";
5121 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
5122 case 0x1300 + 5: return "TCM_GETITEMA";
5123 case 0x1300 + 60: return "TCM_GETITEMW";
5124 case 0x1300 + 6: return "TCM_SETITEMA";
5125 case 0x1300 + 61: return "TCM_SETITEMW";
5126 case 0x1300 + 7: return "TCM_INSERTITEMA";
5127 case 0x1300 + 62: return "TCM_INSERTITEMW";
5128 case 0x1300 + 8: return "TCM_DELETEITEM";
5129 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
5130 case 0x1300 + 10: return "TCM_GETITEMRECT";
5131 case 0x1300 + 11: return "TCM_GETCURSEL";
5132 case 0x1300 + 12: return "TCM_SETCURSEL";
5133 case 0x1300 + 13: return "TCM_HITTEST";
5134 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
5135 case 0x1300 + 40: return "TCM_ADJUSTRECT";
5136 case 0x1300 + 41: return "TCM_SETITEMSIZE";
5137 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
5138 case 0x1300 + 43: return "TCM_SETPADDING";
5139 case 0x1300 + 44: return "TCM_GETROWCOUNT";
5140 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
5141 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
5142 case 0x1300 + 47: return "TCM_GETCURFOCUS";
5143 case 0x1300 + 48: return "TCM_SETCURFOCUS";
5144 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
5145 case 0x1300 + 50: return "TCM_DESELECTALL";
5146
5147 // toolbar
61243a51
DW
5148 case WM_USER+1000+1: return "TB_ENABLEBUTTON";
5149 case WM_USER+1000+2: return "TB_CHECKBUTTON";
5150 case WM_USER+1000+3: return "TB_PRESSBUTTON";
5151 case WM_USER+1000+4: return "TB_HIDEBUTTON";
5152 case WM_USER+1000+5: return "TB_INDETERMINATE";
5153 case WM_USER+1000+9: return "TB_ISBUTTONENABLED";
5154 case WM_USER+1000+10: return "TB_ISBUTTONCHECKED";
5155 case WM_USER+1000+11: return "TB_ISBUTTONPRESSED";
5156 case WM_USER+1000+12: return "TB_ISBUTTONHIDDEN";
5157 case WM_USER+1000+13: return "TB_ISBUTTONINDETERMINATE";
5158 case WM_USER+1000+17: return "TB_SETSTATE";
5159 case WM_USER+1000+18: return "TB_GETSTATE";
5160 case WM_USER+1000+19: return "TB_ADDBITMAP";
5161 case WM_USER+1000+20: return "TB_ADDBUTTONS";
5162 case WM_USER+1000+21: return "TB_INSERTBUTTON";
5163 case WM_USER+1000+22: return "TB_DELETEBUTTON";
5164 case WM_USER+1000+23: return "TB_GETBUTTON";
5165 case WM_USER+1000+24: return "TB_BUTTONCOUNT";
5166 case WM_USER+1000+25: return "TB_COMMANDTOINDEX";
5167 case WM_USER+1000+26: return "TB_SAVERESTOREA";
5168 case WM_USER+1000+76: return "TB_SAVERESTOREW";
5169 case WM_USER+1000+27: return "TB_CUSTOMIZE";
5170 case WM_USER+1000+28: return "TB_ADDSTRINGA";
5171 case WM_USER+1000+77: return "TB_ADDSTRINGW";
5172 case WM_USER+1000+29: return "TB_GETITEMRECT";
5173 case WM_USER+1000+30: return "TB_BUTTONSTRUCTSIZE";
5174 case WM_USER+1000+31: return "TB_SETBUTTONSIZE";
5175 case WM_USER+1000+32: return "TB_SETBITMAPSIZE";
5176 case WM_USER+1000+33: return "TB_AUTOSIZE";
5177 case WM_USER+1000+35: return "TB_GETTOOLTIPS";
5178 case WM_USER+1000+36: return "TB_SETTOOLTIPS";
5179 case WM_USER+1000+37: return "TB_SETPARENT";
5180 case WM_USER+1000+39: return "TB_SETROWS";
5181 case WM_USER+1000+40: return "TB_GETROWS";
5182 case WM_USER+1000+42: return "TB_SETCMDID";
5183 case WM_USER+1000+43: return "TB_CHANGEBITMAP";
5184 case WM_USER+1000+44: return "TB_GETBITMAP";
5185 case WM_USER+1000+45: return "TB_GETBUTTONTEXTA";
5186 case WM_USER+1000+75: return "TB_GETBUTTONTEXTW";
5187 case WM_USER+1000+46: return "TB_REPLACEBITMAP";
5188 case WM_USER+1000+47: return "TB_SETINDENT";
5189 case WM_USER+1000+48: return "TB_SETIMAGELIST";
5190 case WM_USER+1000+49: return "TB_GETIMAGELIST";
5191 case WM_USER+1000+50: return "TB_LOADIMAGES";
5192 case WM_USER+1000+51: return "TB_GETRECT";
5193 case WM_USER+1000+52: return "TB_SETHOTIMAGELIST";
5194 case WM_USER+1000+53: return "TB_GETHOTIMAGELIST";
5195 case WM_USER+1000+54: return "TB_SETDISABLEDIMAGELIST";
5196 case WM_USER+1000+55: return "TB_GETDISABLEDIMAGELIST";
5197 case WM_USER+1000+56: return "TB_SETSTYLE";
5198 case WM_USER+1000+57: return "TB_GETSTYLE";
5199 case WM_USER+1000+58: return "TB_GETBUTTONSIZE";
5200 case WM_USER+1000+59: return "TB_SETBUTTONWIDTH";
5201 case WM_USER+1000+60: return "TB_SETMAXTEXTROWS";
5202 case WM_USER+1000+61: return "TB_GETTEXTROWS";
5203 case WM_USER+1000+41: return "TB_GETBITMAPFLAGS";
cdf1e714
DW
5204
5205 default:
5206 static char s_szBuf[128];
61243a51 5207 sprintf(s_szBuf, "<unknown message = %d>", nMessage);
cdf1e714 5208 return s_szBuf;
86de7616 5209 }
cdf1e714 5210 return NULL;
61243a51 5211} // end of wxGetMessageName
86de7616 5212
11e59d47
DW
5213#endif // __WXDEBUG__
5214
19193a2c
KB
5215// Unused?
5216#if 0
61243a51
DW
5217static void TranslateKbdEventToMouse(
5218 wxWindow* pWin
5219, int* pX
5220, int* pY
5221, ULONG* pFlags
5222)
5223{
5224 //
5225 // Construct the key mask
5226 ULONG& fwKeys = *pFlags;
5227
5228 fwKeys = VK_BUTTON2;
5229 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
5230 fwKeys |= VK_CTRL;
5231 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
5232 fwKeys |= VK_SHIFT;
5233
5234 //
5235 // Simulate right mouse button click
5236 //
5237 POINTL vPoint;
5238
5239 ::WinQueryMsgPos(vHabmain, &vPoint);
5240 *pX = vPoint.x;
5241 *pY = vPoint.y;
5242
5243 pWin->ScreenToClient(pX, pY);
5244} // end of TranslateKbdEventToMouse
19193a2c 5245#endif
61243a51 5246
cd212ee4
DW
5247// Find the wxWindow at the current mouse position, returning the mouse
5248// position.
f44fdfb0 5249wxWindow* wxFindWindowAtPointer(
19193a2c 5250 wxPoint& WXUNUSED(rPt)
f44fdfb0 5251)
cd212ee4
DW
5252{
5253 return wxFindWindowAtPoint(wxGetMousePosition());
5254}
5255
f44fdfb0
DW
5256wxWindow* wxFindWindowAtPoint(
5257 const wxPoint& rPt
5258)
cd212ee4 5259{
f44fdfb0 5260 POINTL vPt2;
cd212ee4 5261
f44fdfb0
DW
5262 vPt2.x = rPt.x;
5263 vPt2.y = rPt.y;
cd212ee4 5264
f44fdfb0
DW
5265 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
5266 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
5267 HWND hWnd = hWndHit;
5268
5269 //
cd212ee4 5270 // Try to find a window with a wxWindow associated with it
f44fdfb0
DW
5271 //
5272 while (!pWin && (hWnd != 0))
cd212ee4 5273 {
f44fdfb0
DW
5274 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
5275 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
cd212ee4 5276 }
f44fdfb0 5277 return pWin;
cd212ee4
DW
5278}
5279
f44fdfb0
DW
5280// Get the current mouse position.
5281wxPoint wxGetMousePosition()
5282{
5283 POINTL vPt;
5284
5285 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
5286 return wxPoint(vPt.x, vPt.y);
5287}
cd212ee4 5288
430974f8
DW
5289wxWindowOS2* FindWindowForMouseEvent(
5290 wxWindow* pWin
5291, short* pnX
5292, short* pnY
5293)
5294{
430974f8
DW
5295 HWND hWnd = GetHwndOf(pWin);
5296 HWND hWndUnderMouse;
b720b24d
DW
5297 POINTL vPoint;
5298 BOOL rcEnabled = FALSE;
5299 BOOL rcVisible = FALSE;
430974f8 5300
b720b24d
DW
5301 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
5302 hWndUnderMouse = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
5303 if (hWndUnderMouse != HWND_DESKTOP)
430974f8 5304 {
b720b24d
DW
5305 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5306
5307 if (pWinUnderMouse)
5308 {
2461cfa0 5309 wxWindowList::compatibility_iterator current = pWinUnderMouse->GetChildren().GetFirst();
b720b24d
DW
5310 wxWindow* pGrandChild = NULL;
5311 RECTL vRect;
5312 POINTL vPoint2;
5313
5314 ::WinMapWindowPoints(HWND_DESKTOP, hWndUnderMouse, &vPoint, 1);
5315 //
5316 // Find a child window mouse might be under
5317 //
2461cfa0 5318 while (current)
b720b24d 5319 {
2461cfa0 5320 wxWindow* pChild = current->GetData();
b720b24d
DW
5321
5322 vPoint2.x = vPoint.x;
5323 vPoint2.y = vPoint.y;
5324 ::WinMapWindowPoints(hWndUnderMouse, pChild->GetHWND(), &vPoint2, 1);
5325 ::WinQueryWindowRect(pChild->GetHWND(), &vRect);
5326 if (::WinPtInRect(vHabmain, &vRect, &vPoint2))
5327 {
5328 if (pChild->IsTopLevel())
5329 {
5330 POINTL vPoint3;
2461cfa0 5331 wxWindowList::compatibility_iterator current2 =pChild->GetChildren().GetFirst();
430974f8 5332
2461cfa0 5333 while (current2)
b720b24d 5334 {
2461cfa0 5335 wxWindow* pGrandChild = current2->GetData();
b720b24d
DW
5336
5337 vPoint3.x = vPoint2.x;
5338 vPoint3.y = vPoint2.y;
5339 ::WinMapWindowPoints( pChild->GetHWND()
5340 ,pGrandChild->GetHWND()
5341 ,&vPoint3
5342 ,1
5343 );
5344 ::WinQueryWindowRect(pGrandChild->GetHWND(), &vRect);
5345 if (::WinPtInRect(vHabmain, &vRect, &vPoint3))
5346 {
5347 hWndUnderMouse = GetHwndOf(pGrandChild);
5348 pWinUnderMouse = pGrandChild;
5349 break;
5350 }
2461cfa0 5351 current2 = current2->GetNext();
b720b24d
DW
5352 }
5353 if (pGrandChild)
5354 break;
5355 }
5356 hWndUnderMouse = GetHwndOf(pChild);
5357 pWinUnderMouse = pChild;
5358 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5359 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5360 if (rcVisible && rcEnabled)
5361 break;
5362 }
2461cfa0 5363 current = current->GetNext();
b720b24d
DW
5364 }
5365 }
430974f8 5366 }
b720b24d
DW
5367 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5368 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5369
430974f8
DW
5370
5371 //
5372 // Check that we have a child window which is susceptible to receive mouse
5373 // events: for this it must be shown and enabled
b720b24d 5374 //
430974f8
DW
5375 if ( hWndUnderMouse &&
5376 hWndUnderMouse != hWnd &&
b720b24d 5377 rcVisible && rcEnabled)
430974f8 5378 {
b720b24d
DW
5379 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5380
430974f8
DW
5381 if (pWinUnderMouse)
5382 {
b720b24d
DW
5383 //
5384 // Translate the mouse coords to the other window coords
5385 //
430974f8
DW
5386 pWin = pWinUnderMouse;
5387 }
5388 }
5389 return pWin;
5390} // end of FindWindowForMouseEvent
5391