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