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