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