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