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