]> git.saurik.com Git - wxWidgets.git/blame - src/os2/window.cpp
Font (possible) fix
[wxWidgets.git] / src / os2 / window.cpp
CommitLineData
77f4f0a7 1/////////////////////////////////////////////////////////////////////////////
0e320a79
DW
2// Name: windows.cpp
3// Purpose: wxWindow
cdf1e714 4// Author: David Webster
0e320a79 5// Modified by:
cdf1e714 6// Created: 10/12/99
0e320a79 7// RCS-ID: $Id$
cdf1e714 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
a885d89a 12//
cdf1e714 13// For compilers that support precompilation, includes "wx.h".
a885d89a 14//
cdf1e714 15#include "wx/wxprec.h"
0e320a79 16
849949b1
DW
17#ifndef WX_PRECOMP
18 #define INCL_DOS
19 #define INCL_PM
20 #include <os2.h>
21 #include "wx/window.h"
22 #include "wx/accel.h"
23 #include "wx/setup.h"
24 #include "wx/menu.h"
25 #include "wx/dc.h"
26 #include "wx/dcclient.h"
27 #include "wx/utils.h"
28 #include "wx/app.h"
29 #include "wx/panel.h"
30 #include "wx/layout.h"
1a75e76f
SN
31 #include "wx/checkbox.h"
32 #include "wx/combobox.h"
849949b1
DW
33 #include "wx/dialog.h"
34 #include "wx/frame.h"
35 #include "wx/listbox.h"
36 #include "wx/button.h"
376ef4a1 37 #include "wx/bmpbuttn.h"
849949b1 38 #include "wx/msgdlg.h"
19193a2c 39 #include "wx/scrolwin.h"
a4a16252 40 #include "wx/radiobox.h"
1a75e76f 41 #include "wx/radiobut.h"
a4a16252 42 #include "wx/slider.h"
272ebf16 43 #include "wx/statbox.h"
a4a16252
SN
44 #include "wx/statusbr.h"
45 #include "wx/toolbar.h"
46 #include "wx/settings.h"
849949b1
DW
47 #include <stdio.h>
48#endif
49
ebeb1b6a 50#if wxUSE_OWNER_DRAWN
849949b1
DW
51 #include "wx/ownerdrw.h"
52#endif
53
54#if wxUSE_DRAG_AND_DROP
55 #include "wx/dnd.h"
56#endif
0e320a79
DW
57
58#include "wx/menuitem.h"
59#include "wx/log.h"
60
cdf1e714
DW
61#include "wx/os2/private.h"
62
849949b1
DW
63#if wxUSE_TOOLTIPS
64 #include "wx/tooltip.h"
0e320a79
DW
65#endif
66
1de4baa3
DW
67#if wxUSE_NOTEBOOK
68 #include "wx/notebook.h"
69#endif
70
849949b1
DW
71#if wxUSE_CARET
72 #include "wx/caret.h"
73#endif // wxUSE_CARET
74
75#include "wx/intl.h"
76#include "wx/log.h"
77
78
79#include "wx/textctrl.h"
80
0e320a79
DW
81#include <string.h>
82
a885d89a
DW
83//
84// Place compiler, OS specific includes here
85//
849949b1 86
a885d89a
DW
87//
88// Standard macros -- these are for OS/2 PM, but most GUI's have something similar
89//
849949b1 90#ifndef GET_X_LPARAM
a885d89a 91//
849949b1 92// SHORT1FROMMP -- LOWORD
a885d89a 93//
849949b1 94 #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp))
a885d89a 95//
849949b1 96// SHORT2FROMMP -- HIWORD
a885d89a 97//
849949b1
DW
98 #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16))
99#endif // GET_X_LPARAM
100
29a99be3
DW
101#ifndef CW_USEDEFAULT
102# define CW_USEDEFAULT ((int)0x80000000)
103#endif
104
a086de98
DW
105#ifndef VK_OEM_1
106 #define VK_OEM_1 0xBA
107 #define VK_OEM_PLUS 0xBB
108 #define VK_OEM_COMMA 0xBC
109 #define VK_OEM_MINUS 0xBD
110 #define VK_OEM_PERIOD 0xBE
111 #define VK_OEM_2 0xBF
112 #define VK_OEM_3 0xC0
113 #define VK_OEM_4 0xDB
114 #define VK_OEM_5 0xDC
115 #define VK_OEM_6 0xDD
116 #define VK_OEM_7 0xDE
117#endif
118
849949b1
DW
119// ---------------------------------------------------------------------------
120// global variables
121// ---------------------------------------------------------------------------
122
a885d89a 123//
19193a2c 124// The last PM message we got (MT-UNSAFE)
a885d89a 125//
61243a51 126QMSG s_currentMsg;
849949b1 127
19193a2c 128#if wxUSE_MENUS_NATIVE
a885d89a 129wxMenu* wxCurrentPopupMenu = NULL;
19193a2c
KB
130#endif // wxUSE_MENUS_NATIVE
131
849949b1
DW
132// ---------------------------------------------------------------------------
133// private functions
134// ---------------------------------------------------------------------------
a885d89a
DW
135
136//
849949b1 137// the window proc for all our windows; most gui's have something similar
a885d89a 138//
f23208ca
DW
139MRESULT EXPENTRY wxWndProc( HWND hWnd
140 ,ULONG message
141 ,MPARAM mp1
142 ,MPARAM mp2
143 );
11e59d47
DW
144
145#ifdef __WXDEBUG__
4a712ba3 146 const wxChar *wxGetMessageName(int message);
11e59d47
DW
147#endif //__WXDEBUG__
148
430974f8
DW
149wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin
150 ,short* pnX
151 ,short* pnY
152 );
153void wxRemoveHandleAssociation(wxWindowOS2* pWin);
154void wxAssociateWinWithHandle( HWND hWnd
155 ,wxWindowOS2* pWin
156 );
a885d89a 157wxWindow* wxFindWinFromHandle(WXHWND hWnd);
849949b1 158
a885d89a
DW
159//
160// get the current state of SHIFT/CTRL keys
161//
162static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
163static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
06519806
DW
164
165static wxWindow* gpWinBeingCreated = NULL;
166
849949b1
DW
167// ---------------------------------------------------------------------------
168// event tables
169// ---------------------------------------------------------------------------
0e320a79 170
19193a2c
KB
171// in wxUniv-OS/2 this class is abstract because it doesn't have DoPopupMenu()
172// method
173#ifdef __WXUNIVERSAL__
174 IMPLEMENT_ABSTRACT_CLASS(wxWindowOS2, wxWindowBase)
175#else // __WXPM__
849949b1 176 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
19193a2c 177#endif // __WXUNIVERSAL__/__WXPM__
0e320a79 178
19193a2c 179BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
0367c1c0
DW
180 EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
181 EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
0367c1c0
DW
182 EVT_IDLE(wxWindowOS2::OnIdle)
183 EVT_SET_FOCUS(wxWindowOS2::OnSetFocus)
849949b1 184END_EVENT_TABLE()
0e320a79 185
849949b1
DW
186// ===========================================================================
187// implementation
188// ===========================================================================
0e320a79 189
19193a2c
KB
190// ---------------------------------------------------------------------------
191// wxWindow utility functions
192// ---------------------------------------------------------------------------
193
a885d89a 194//
776d87d5 195// Find an item given the PM Window id
a885d89a 196//
0367c1c0 197wxWindow* wxWindowOS2::FindItem(
a885d89a 198 long lId
776d87d5 199) const
cdf1e714 200{
19193a2c
KB
201#if wxUSE_CONTROLS
202 wxControl* pItem = wxDynamicCast(this, wxControl);
a885d89a
DW
203
204 if (pItem)
205 {
206 //
207 // I it we or one of our "internal" children?
208 //
19193a2c
KB
209 if (pItem->GetId() == lId
210#ifndef __WXUNIVERSAL__
211 || (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)
212#endif
213 )
a885d89a
DW
214 {
215 return pItem;
216 }
217 }
19193a2c 218#endif // wxUSE_CONTROLS
a885d89a 219
2461cfa0 220 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
776d87d5 221
2461cfa0 222 while (current)
cdf1e714 223 {
2461cfa0 224 wxWindow* pChildWin = current->GetData();
a885d89a 225 wxWindow* pWnd = pChildWin->FindItem(lId);
cdf1e714 226
776d87d5
DW
227 if (pWnd)
228 return pWnd;
cdf1e714 229
2461cfa0 230 current = current->GetNext();
cdf1e714 231 }
776d87d5 232 return(NULL);
0367c1c0 233} // end of wxWindowOS2::FindItem
cdf1e714 234
a885d89a 235//
776d87d5 236// Find an item given the PM Window handle
a885d89a 237//
0367c1c0 238wxWindow* wxWindowOS2::FindItemByHWND(
776d87d5
DW
239 WXHWND hWnd
240, bool bControlOnly
241) const
cdf1e714 242{
2461cfa0 243 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
776d87d5 244
2461cfa0 245 while (current)
cdf1e714 246 {
2461cfa0 247 wxWindow* pParent = current->GetData();
cdf1e714 248
a885d89a 249 //
cdf1e714 250 // Do a recursive search.
a885d89a 251 //
776d87d5
DW
252 wxWindow* pWnd = pParent->FindItemByHWND(hWnd);
253
254 if (pWnd)
255 return(pWnd);
cdf1e714 256
19193a2c
KB
257 if (!bControlOnly
258#if wxUSE_CONTROLS
259 || pParent->IsKindOf(CLASSINFO(wxControl))
260#endif // wxUSE_CONTROLS
261 )
cdf1e714 262 {
2461cfa0 263 wxWindow* pItem = current->GetData();
776d87d5
DW
264
265 if (pItem->GetHWND() == hWnd)
266 return(pItem);
cdf1e714
DW
267 else
268 {
776d87d5
DW
269 if (pItem->ContainsHWND(hWnd))
270 return(pItem);
cdf1e714
DW
271 }
272 }
2461cfa0 273 current = current->GetNext();
cdf1e714 274 }
776d87d5 275 return(NULL);
0367c1c0 276} // end of wxWindowOS2::FindItemByHWND
cdf1e714 277
a885d89a 278//
cdf1e714 279// Default command handler
a885d89a 280//
77f4f0a7
WS
281bool wxWindowOS2::OS2Command( WXUINT WXUNUSED(uParam),
282 WXWORD WXUNUSED(uId) )
cdf1e714 283{
77f4f0a7 284 return false;
cdf1e714
DW
285}
286
287// ----------------------------------------------------------------------------
288// constructors and such
289// ----------------------------------------------------------------------------
290
0367c1c0 291void wxWindowOS2::Init()
0e320a79 292{
a885d89a 293 //
849949b1 294 // PM specific
a885d89a 295 //
77f4f0a7 296 m_bWinCaptured = false;
cdf1e714 297
47df2b8c 298 m_fnOldWndProc = NULL;
77f4f0a7
WS
299 m_bUseCtl3D = false;
300 m_bMouseInWindow = false;
301 m_bLastKeydownProcessed = false;
cfcebdb1 302 m_pChildrenDisabled = NULL;
0e320a79 303
a885d89a 304 //
849949b1 305 // wxWnd
a885d89a 306 //
c8b5f745
DW
307 m_hMenu = 0L;
308 m_hWnd = 0L;
309 m_hWndScrollBarHorz = 0L;
310 m_hWndScrollBarVert = 0L;
0e320a79 311
4a46a5df
DW
312 memset(&m_vWinSwp, '\0', sizeof (SWP));
313
a885d89a
DW
314 //
315 // Pass WM_GETDLGCODE to DefWindowProc()
4a46a5df 316 //
849949b1 317 m_lDlgCode = 0;
0e320a79 318
776d87d5
DW
319 m_nXThumbSize = 0;
320 m_nYThumbSize = 0;
77f4f0a7 321 m_bBackgroundTransparent = false;
0e320a79 322
a885d89a
DW
323 //
324 // As all windows are created with WS_VISIBLE style...
325 //
77f4f0a7 326 m_isShown = true;
0e320a79 327
cdf1e714 328#if wxUSE_MOUSEEVENT_HACK
776d87d5
DW
329 m_lLastMouseX =
330 m_lLastMouseY = -1;
331 m_nLastMouseEvent = -1;
cdf1e714 332#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 333} // wxWindowOS2::Init
0e320a79 334
a885d89a 335//
849949b1 336// Destructor
a885d89a 337//
0367c1c0 338wxWindowOS2::~wxWindowOS2()
0e320a79 339{
77f4f0a7 340 m_isBeingDeleted = true;
0e320a79 341
1ec46a5b
DW
342 for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
343 {
47df2b8c 344 wxTopLevelWindow* pFrame = wxDynamicCast(pWin, wxTopLevelWindow);
1ec46a5b
DW
345
346 if (pFrame)
347 {
348 if (pFrame->GetLastFocus() == this)
47df2b8c 349 pFrame->SetLastFocus(NULL);
1ec46a5b
DW
350 }
351 }
19193a2c
KB
352
353 DestroyChildren();
354
849949b1
DW
355 if (m_hWnd)
356 {
a885d89a 357 if(!::WinDestroyWindow(GetHWND()))
223d09f6 358 wxLogLastError(wxT("DestroyWindow"));
a885d89a 359 //
849949b1 360 // remove hWnd <-> wxWindow association
a885d89a 361 //
849949b1
DW
362 wxRemoveHandleAssociation(this);
363 }
cfcebdb1 364 delete m_pChildrenDisabled;
0367c1c0 365} // end of wxWindowOS2::~wxWindowOS2
0e320a79 366
19193a2c 367// real construction (Init() must have been called before!)
77f4f0a7
WS
368bool wxWindowOS2::Create( wxWindow* pParent,
369 wxWindowID vId,
370 const wxPoint& rPos,
371 const wxSize& rSize,
372 long lStyle,
373 const wxString& rName )
776d87d5 374{
77f4f0a7
WS
375 HWND hParent = NULLHANDLE;
376 ULONG ulCreateFlags = 0;
377 WXDWORD dwExStyle = 0;
f23208ca 378
77f4f0a7 379 wxCHECK_MSG(pParent, false, wxT("can't create wxWindow without parent"));
776d87d5 380
b9b1d6c8
DW
381#if wxUSE_STATBOX
382 //
383 // wxGTK doesn't allow to create controls with static box as the parent so
384 // this will result in a crash when the program is ported to wxGTK - warn
385 // about it
386 //
387 // the correct solution is to create the controls as siblings of the
388 // static box
389 //
390 wxASSERT_MSG( !wxDynamicCast(pParent, wxStaticBox),
391 _T("wxStaticBox can't be used as a window parent!") );
392#endif // wxUSE_STATBOX
393
916a68fa
SN
394 // Ensure groupbox backgrounds are painted
395 if (IsKindOf(CLASSINFO(wxPanel)))
396 lStyle &= ~wxCLIP_CHILDREN;
397
776d87d5
DW
398 if ( !CreateBase( pParent
399 ,vId
400 ,rPos
401 ,rSize
402 ,lStyle
403 ,wxDefaultValidator
404 ,rName
405 ))
77f4f0a7 406 return false;
776d87d5 407
f23208ca
DW
408 if (pParent)
409 {
410 pParent->AddChild(this);
411 hParent = GetWinHwnd(pParent);
cb71578c 412
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
77f4f0a7 577void wxWindowOS2::SetTitle( const wxString& rTitle )
0e320a79 578{
0fba44b4 579 ::WinSetWindowText(GetHwnd(), (PSZ)rTitle.c_str());
0367c1c0 580} // end of wxWindowOS2::SetTitle
0e320a79 581
0367c1c0 582wxString wxWindowOS2::GetTitle() const
0e320a79 583{
cdf1e714 584 return wxGetWindowText(GetHWND());
0367c1c0 585} // end of wxWindowOS2::GetTitle
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 }
0367c1c0 596} // end of wxWindowOS2::GetTitle
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
987da0d4
DW
1812 l = rString.Length();
1813 if (l > 0L)
1814 {
1815 pStr = (PCH)rString.c_str();
a7ef993c 1816
987da0d4
DW
1817 //
1818 // In world coordinates.
1819 //
1820 bRc = ::GpiQueryTextBox( hPS
1821 ,l
1822 ,pStr
1823 ,TXTBOX_COUNT // return maximum information
1824 ,avPoint // array of coordinates points
1825 );
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
77f4f0a7
WS
1913bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu,
1914 int nX,
1915 int nY )
cdf1e714 1916{
77f4f0a7
WS
1917 HWND hWndOwner = GetHwnd();
1918 HWND hWndParent = GetHwnd();
1919 HWND hMenu = GetHmenuOf(pMenu);
1920 bool bIsWaiting = true;
1921 int nHeight;
c82be69b
JS
1922
1923 // Protect against recursion
1924 if (wxCurrentPopupMenu)
1925 return false;
61243a51
DW
1926
1927 pMenu->SetInvokingWindow(this);
1928 pMenu->UpdateUI();
c82be69b 1929
5d826f60 1930 if ( nX == -1 && nY == -1 )
971562cb
VS
1931 {
1932 wxPoint mouse = wxGetMousePosition();
1933 nX = mouse.x; nY = mouse.y;
1934 }
1935 else
1936 {
1937 DoClientToScreen( &nX
1938 ,&nY
1939 );
c82be69b
JS
1940 DoGetSize(0,&nHeight);
1941 nY = nHeight - nY;
971562cb 1942 }
61243a51
DW
1943 wxCurrentPopupMenu = pMenu;
1944
1945 ::WinPopupMenu( hWndParent
239c2e96 1946 ,hWndOwner
61243a51
DW
1947 ,hMenu
1948 ,nX
1949 ,nY
1950 ,0L
bdfd8d77 1951 ,PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 | PU_KEYBOARD
61243a51 1952 );
bdfd8d77 1953
239c2e96
DW
1954 while(bIsWaiting)
1955 {
bdfd8d77 1956 QMSG vMsg;
239c2e96 1957
c82be69b
JS
1958 ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
1959 if (vMsg.msg == WM_COMMAND)
77f4f0a7 1960 bIsWaiting = false;
bdfd8d77 1961 ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
239c2e96 1962 }
c82be69b 1963
61243a51 1964 wxCurrentPopupMenu = NULL;
61243a51 1965 pMenu->SetInvokingWindow(NULL);
77f4f0a7 1966 return true;
0367c1c0 1967} // end of wxWindowOS2::DoPopupMenu
19193a2c 1968#endif // wxUSE_MENUS_NATIVE
cdf1e714
DW
1969
1970// ===========================================================================
1971// pre/post message processing
1972// ===========================================================================
1973
77f4f0a7
WS
1974MRESULT wxWindowOS2::OS2DefWindowProc( WXUINT uMsg,
1975 WXWPARAM wParam,
1976 WXLPARAM lParam )
cdf1e714 1977{
61243a51 1978 if (m_fnOldWndProc)
19193a2c 1979 return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
61243a51 1980 else
19193a2c 1981 return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
0367c1c0 1982} // end of wxWindowOS2::OS2DefWindowProc
cdf1e714 1983
77f4f0a7 1984bool wxWindowOS2::OS2ProcessMessage( WXMSG* pMsg )
cdf1e714 1985{
19193a2c
KB
1986// wxUniversal implements tab traversal itself
1987#ifndef __WXUNIVERSAL__
61243a51
DW
1988 QMSG* pQMsg = (QMSG*)pMsg;
1989
1990 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
1991 {
1992 //
1993 // Intercept dialog navigation keys
1994 //
77f4f0a7
WS
1995 bool bProcess = true;
1996 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
61243a51
DW
1997
1998 if (uKeyFlags & KC_KEYUP)
77f4f0a7 1999 bProcess = false;
61243a51
DW
2000
2001 if (uKeyFlags & KC_ALT)
77f4f0a7 2002 bProcess = false;
61243a51
DW
2003
2004 if (!(uKeyFlags & KC_VIRTUALKEY))
77f4f0a7 2005 bProcess = false;
61243a51
DW
2006
2007 if (bProcess)
2008 {
2009 bool bCtrlDown = IsCtrlDown();
2010 bool bShiftDown = IsShiftDown();
2011
2012 //
2013 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
2014 // don't process it if it's the case (except for Ctrl-Tab/Enter
2015 // combinations which are always processed)
2016 //
2017 ULONG ulDlgCode = 0;
2018
2019 if (!bCtrlDown)
2020 {
2021 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
2022 }
2023
77f4f0a7
WS
2024 bool bForward = true;
2025 bool bWindowChange = false;
61243a51
DW
2026
2027 switch (SHORT2FROMMP(pQMsg->mp2))
2028 {
2029 //
2030 // Going to make certain assumptions about specific types of controls
2031 // here, so we may have to alter some things later if they prove invalid
2032 //
2033 case VK_TAB:
2034 //
2035 // Shift tabl will always be a nav-key but tabs may be wanted
2036 //
2037 if (!bShiftDown)
2038 {
77f4f0a7 2039 bProcess = false;
61243a51
DW
2040 }
2041 else
2042 {
2043 //
2044 // Entry Fields want tabs for themselve usually
2045 //
2046 switch (ulDlgCode)
2047 {
2048 case DLGC_ENTRYFIELD:
2049 case DLGC_MLE:
77f4f0a7 2050 bProcess = true;
61243a51
DW
2051 break;
2052
2053 default:
77f4f0a7 2054 bProcess = false;
61243a51
DW
2055 }
2056
2057 //
2058 // Ctrl-Tab cycles thru notebook pages
2059 //
2060 bWindowChange = bCtrlDown;
2061 bForward = !bShiftDown;
2062 }
2063 break;
2064
2065 case VK_UP:
2066 case VK_LEFT:
2067 if (bCtrlDown)
77f4f0a7 2068 bProcess = false;
61243a51 2069 else
77f4f0a7 2070 bForward = false;
61243a51
DW
2071 break;
2072
2073 case VK_DOWN:
2074 case VK_RIGHT:
2075 if (bCtrlDown)
77f4f0a7 2076 bProcess = false;
61243a51
DW
2077 break;
2078
2079 case VK_ENTER:
2080 {
2081 if (bCtrlDown)
2082 {
2083 //
2084 // ctrl-enter is not processed
2085 //
77f4f0a7 2086 return false;
61243a51
DW
2087 }
2088 else if (ulDlgCode & DLGC_BUTTON)
2089 {
2090 //
2091 // buttons want process Enter themselevs
2092 //
77f4f0a7 2093 bProcess = false;
61243a51
DW
2094 }
2095 else
2096 {
1bcfc0e1
DW
2097 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
2098 ,wxButton
2099 );
61243a51
DW
2100
2101 if (pBtn && pBtn->IsEnabled())
2102 {
2103 //
2104 // If we do have a default button, do press it
2105 //
2106 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
77f4f0a7 2107 return true;
61243a51 2108 }
2b5f62a0
VZ
2109 else if (!IsTopLevel())
2110 {
2111 //
2112 // if not a top level window, let parent
2113 // handle it
2114 //
77f4f0a7 2115 return false;
2b5f62a0 2116 }
61243a51
DW
2117 // else: but if it does not it makes sense to make
2118 // it work like a TAB - and that's what we do.
2119 // Note that Ctrl-Enter always works this way.
2120 }
2121 }
2122 break;
2123
2124 default:
77f4f0a7 2125 bProcess = false;
61243a51
DW
2126 }
2127
2128 if (bProcess)
2129 {
2130 wxNavigationKeyEvent vEvent;
2131
2132 vEvent.SetDirection(bForward);
2133 vEvent.SetWindowChange(bWindowChange);
2134 vEvent.SetEventObject(this);
2135
2136 if (GetEventHandler()->ProcessEvent(vEvent))
2137 {
2138 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2139
2140 if (pBtn)
2141 {
2142 //
2143 // The button which has focus should be default
2144 //
2145 pBtn->SetDefault();
2146 }
77f4f0a7 2147 return true;
61243a51
DW
2148 }
2149 }
2150 }
dae16775
DW
2151 //
2152 // Let Dialogs process
2153 //
2154 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
77f4f0a7 2155 return true;
61243a51 2156 }
19193a2c
KB
2157#else
2158 pMsg = pMsg; // just shut up the compiler
2159#endif // __WXUNIVERSAL__
61243a51 2160
77f4f0a7 2161 return false;
0367c1c0 2162} // end of wxWindowOS2::OS2ProcessMessage
cdf1e714 2163
77f4f0a7 2164bool wxWindowOS2::OS2TranslateMessage( WXMSG* pMsg )
cdf1e714 2165{
19193a2c 2166#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
77f4f0a7 2167 return m_acceleratorTable.Translate(m_hWnd, pMsg);
7e99520b 2168#else
77f4f0a7
WS
2169 pMsg = pMsg;
2170 return false;
7e99520b 2171#endif //wxUSE_ACCEL
0367c1c0 2172} // end of wxWindowOS2::OS2TranslateMessage
cdf1e714 2173
6670f564 2174bool wxWindowOS2::OS2ShouldPreProcessMessage( WXMSG* WXUNUSED(pMsg) )
54ffa107
DW
2175{
2176 // preprocess all messages by default
6670f564 2177 return true;
54ffa107
DW
2178} // end of wxWindowOS2::OS2ShouldPreProcessMessage
2179
cdf1e714 2180// ---------------------------------------------------------------------------
61243a51 2181// message params unpackers
cdf1e714
DW
2182// ---------------------------------------------------------------------------
2183
0367c1c0 2184void wxWindowOS2::UnpackCommand(
61243a51
DW
2185 WXWPARAM wParam
2186, WXLPARAM lParam
2187, WORD* pId
2188, WXHWND* phWnd
2189, WORD* pCmd
2190)
cdf1e714 2191{
5b3ed311
DW
2192 *pId = LOWORD(wParam);
2193 *phWnd = NULL; // or may be GetHWND() ?
2194 *pCmd = LOWORD(lParam);
0367c1c0 2195} // end of wxWindowOS2::UnpackCommand
cdf1e714 2196
0367c1c0 2197void wxWindowOS2::UnpackActivate(
61243a51
DW
2198 WXWPARAM wParam
2199, WXLPARAM lParam
2200, WXWORD* pState
2201, WXHWND* phWnd
2202)
cdf1e714 2203{
61243a51
DW
2204 *pState = LOWORD(wParam);
2205 *phWnd = (WXHWND)lParam;
0367c1c0 2206} // end of wxWindowOS2::UnpackActivate
cdf1e714 2207
0367c1c0 2208void wxWindowOS2::UnpackScroll(
61243a51
DW
2209 WXWPARAM wParam
2210, WXLPARAM lParam
2211, WXWORD* pCode
2212, WXWORD* pPos
2213, WXHWND* phWnd
2214)
cdf1e714 2215{
b7d8f285
DW
2216 ULONG ulId;
2217 HWND hWnd;
2218
2219 ulId = (ULONG)LONGFROMMP(wParam);
2220 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2221 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2222 *phWnd = NULLHANDLE;
2223 else
2224 *phWnd = hWnd;
2225
2226 *pPos = SHORT1FROMMP(lParam);
2227 *pCode = SHORT2FROMMP(lParam);
0367c1c0 2228} // end of wxWindowOS2::UnpackScroll
61243a51 2229
0367c1c0 2230void wxWindowOS2::UnpackMenuSelect(
61243a51
DW
2231 WXWPARAM wParam
2232, WXLPARAM lParam
2233, WXWORD* pItem
2234, WXWORD* pFlags
2235, WXHMENU* phMenu
2236)
cdf1e714 2237{
61243a51
DW
2238 *pItem = (WXWORD)LOWORD(wParam);
2239 *pFlags = HIWORD(wParam);
2240 *phMenu = (WXHMENU)lParam;
0367c1c0 2241} // end of wxWindowOS2::UnpackMenuSelect
cdf1e714
DW
2242
2243// ---------------------------------------------------------------------------
77ffb593 2244// Main wxWidgets window proc and the window proc for wxWindow
cdf1e714
DW
2245// ---------------------------------------------------------------------------
2246
61243a51 2247//
cdf1e714
DW
2248// Hook for new window just as it's being created, when the window isn't yet
2249// associated with the handle
61243a51 2250//
19193a2c 2251wxWindowOS2* wxWndHook = NULL;
cdf1e714 2252
61243a51 2253//
cdf1e714 2254// Main window proc
61243a51 2255//
f23208ca 2256MRESULT EXPENTRY wxWndProc(
61243a51
DW
2257 HWND hWnd
2258, ULONG ulMsg
2259, MPARAM wParam
2260, MPARAM lParam
2261)
cdf1e714 2262{
19193a2c 2263 wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
cdf1e714 2264
61243a51
DW
2265 //
2266 // When we get the first message for the HWND we just created, we associate
cdf1e714 2267 // it with wxWindow stored in wxWndHook
61243a51
DW
2268 //
2269 if (!pWnd && wxWndHook)
cdf1e714 2270 {
cdf1e714 2271 wxAssociateWinWithHandle(hWnd, wxWndHook);
61243a51 2272 pWnd = wxWndHook;
cdf1e714 2273 wxWndHook = NULL;
61243a51 2274 pWnd->SetHWND((WXHWND)hWnd);
cdf1e714
DW
2275 }
2276
5b3ed311 2277 MRESULT rc = (MRESULT)0;
e604d44b 2278
cdf1e714 2279
61243a51 2280 //
cdf1e714 2281 // Stop right here if we don't have a valid handle in our wxWindow object.
61243a51
DW
2282 //
2283 if (pWnd && !pWnd->GetHWND())
cdf1e714 2284 {
61243a51
DW
2285 pWnd->SetHWND((WXHWND) hWnd);
2286 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2287 pWnd->SetHWND(0);
cdf1e714
DW
2288 }
2289 else
2290 {
61243a51 2291 if (pWnd)
45e0dc94 2292 {
61243a51 2293 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
45e0dc94
DW
2294 if ( (pWnd->GetScrollBarHorz() != NULLHANDLE ||
2295 pWnd->GetScrollBarVert() != NULLHANDLE) &&
2296 ulMsg == WM_PAINT)
2297 {
2298 if (pWnd->GetScrollBarHorz() != NULLHANDLE)
2299 ::WinInvalidateRect(pWnd->GetScrollBarHorz(), NULL, TRUE);
2300 if (pWnd->GetScrollBarVert() != NULLHANDLE)
2301 ::WinInvalidateRect(pWnd->GetScrollBarVert(), NULL, TRUE);
2302 }
2303 }
e604d44b 2304 else
61243a51 2305 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
cdf1e714 2306 }
5b3ed311 2307
cdf1e714 2308 return rc;
61243a51 2309} // end of wxWndProc
cdf1e714 2310
61243a51
DW
2311//
2312// We will add (or delete) messages we need to handle at this default
2313// level as we go
2314//
77f4f0a7
WS
2315MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
2316 WXWPARAM wParam,
2317 WXLPARAM lParam )
cdf1e714 2318{
61243a51
DW
2319 //
2320 // Did we process the uMsg?
2321 //
77f4f0a7
WS
2322 bool bProcessed = false;
2323 MRESULT mResult;
cdf1e714 2324
61243a51
DW
2325 //
2326 // For most messages we should return 0 when we do process the message
2327 //
e604d44b 2328 mResult = (MRESULT)0;
61243a51
DW
2329
2330 switch (uMsg)
cdf1e714
DW
2331 {
2332 case WM_CREATE:
2333 {
61243a51
DW
2334 bool bMayCreate;
2335
2336 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2337 ,&bMayCreate
2338 );
2339 if (bProcessed)
cdf1e714 2340 {
61243a51
DW
2341 //
2342 // Return 0 to bAllow window creation
2343 //
e604d44b 2344 mResult = (MRESULT)(bMayCreate ? 0 : -1);
cdf1e714
DW
2345 }
2346 }
2347 break;
2348
2349 case WM_DESTROY:
e604d44b 2350 HandleDestroy();
77f4f0a7 2351 bProcessed = true;
e604d44b 2352 break;
cdf1e714
DW
2353
2354 case WM_MOVE:
61243a51
DW
2355 bProcessed = HandleMove( LOWORD(lParam)
2356 ,HIWORD(lParam)
2357 );
cdf1e714
DW
2358 break;
2359
2360 case WM_SIZE:
61243a51
DW
2361 bProcessed = HandleSize( LOWORD(lParam)
2362 ,HIWORD(lParam)
2363 ,(WXUINT)wParam
2364 );
cdf1e714
DW
2365 break;
2366
e37db699
DW
2367 case WM_WINDOWPOSCHANGED:
2368
2369 //
2370 // Dialogs under OS/2 do not get WM_SIZE events at all.
2371 // Instead they get this, which can function much like WM_SIZE
2372 // PSWP contains the new sizes and positioning, PSWP+1 the old
2373 // We use this because ADJUSTWINDOWPOS comes BEFORE the new
2374 // position is added and our auto layout does a WinQueryWindowRect
2375 // to get the CURRENT client size. That is the size used to position
2376 // child controls, so we need to already be sized
2377 // in order to get the child controls positoned properly.
2378 //
626af800 2379 if (IsKindOf(CLASSINFO(wxDialog)) || IsKindOf(CLASSINFO(wxFrame)))
e37db699
DW
2380 {
2381 PSWP pSwp = (PSWP)PVOIDFROMMP(wParam);
f3e4a2a4
DW
2382 PSWP pSwp2 = pSwp++;
2383
2384 if (!(pSwp->cx == pSwp2->cx &&
2385 pSwp->cy == pSwp2->cy))
2386 bProcessed = HandleSize( pSwp->cx
2387 ,pSwp->cy
2388 ,(WXUINT)lParam
2389 );
626af800
DW
2390 if (IsKindOf(CLASSINFO(wxFrame)))
2391 {
2392 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
2393
2394 if (pFrame)
2395 {
2396 if (pFrame->GetStatusBar())
2397 pFrame->PositionStatusBar();
2590f154
DW
2398 if (pFrame->GetToolBar())
2399 pFrame->PositionToolBar();
626af800
DW
2400 }
2401 }
e37db699
DW
2402 }
2403 break;
2404
cdf1e714
DW
2405 case WM_ACTIVATE:
2406 {
61243a51
DW
2407 WXWORD wState;
2408 WXHWND hWnd;
2409
2410 UnpackActivate( wParam
2411 ,lParam
2412 ,&wState
2413 ,&hWnd
2414 );
2415
2416 bProcessed = HandleActivate( wState
2417 ,(WXHWND)hWnd
2418 );
77f4f0a7 2419 bProcessed = false;
cdf1e714
DW
2420 }
2421 break;
2422
2423 case WM_SETFOCUS:
61243a51
DW
2424 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2425 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2426 else
2427 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
cdf1e714
DW
2428 break;
2429
2430 case WM_PAINT:
61243a51 2431 bProcessed = HandlePaint();
cdf1e714
DW
2432 break;
2433
2434 case WM_CLOSE:
61243a51
DW
2435 //
2436 // Don't let the DefWindowProc() destroy our window - we'll do it
cdf1e714 2437 // ourselves in ~wxWindow
61243a51 2438 //
77f4f0a7 2439 bProcessed = true;
e604d44b 2440 mResult = (MRESULT)TRUE;
cdf1e714
DW
2441 break;
2442
61243a51
DW
2443 case WM_SHOW:
2444 bProcessed = HandleShow(wParam != 0, (int)lParam);
cdf1e714
DW
2445 break;
2446
61243a51
DW
2447 //
2448 // Under OS2 PM Joysticks are treated just like mouse events
2449 // The "Motion" events will be prevelent in joysticks
2450 //
cdf1e714 2451 case WM_MOUSEMOVE:
61243a51
DW
2452 case WM_BUTTON1DOWN:
2453 case WM_BUTTON1UP:
2454 case WM_BUTTON1DBLCLK:
2455 case WM_BUTTON1MOTIONEND:
2456 case WM_BUTTON1MOTIONSTART:
2457 case WM_BUTTON2DOWN:
2458 case WM_BUTTON2UP:
2459 case WM_BUTTON2DBLCLK:
2460 case WM_BUTTON2MOTIONEND:
2461 case WM_BUTTON2MOTIONSTART:
2462 case WM_BUTTON3DOWN:
2463 case WM_BUTTON3UP:
2464 case WM_BUTTON3DBLCLK:
2465 case WM_BUTTON3MOTIONEND:
2466 case WM_BUTTON3MOTIONSTART:
cdf1e714 2467 {
430974f8
DW
2468 if (uMsg == WM_BUTTON1DOWN && AcceptsFocus())
2469 SetFocus();
2470
2471 short nX = LOWORD(wParam);
2472 short nY = HIWORD(wParam);
cdf1e714 2473
430974f8
DW
2474 //
2475 // Redirect the event to a static control if necessary
2476 //
2477 if (this == GetCapture())
2478 {
2479 bProcessed = HandleMouseEvent( uMsg
2480 ,nX
2481 ,nY
8d902dd6 2482 ,(WXUINT)SHORT2FROMMP(lParam)
430974f8
DW
2483 );
2484 }
2485 else
2486 {
2487 wxWindow* pWin = FindWindowForMouseEvent( this
2488 ,&nX
2489 ,&nY
2490 );
376ef4a1
DW
2491 if (!pWin->IsOfStandardClass())
2492 {
2493 if (uMsg == WM_BUTTON1DOWN && pWin->AcceptsFocus() )
2494 pWin->SetFocus();
2495 }
430974f8
DW
2496 bProcessed = pWin->HandleMouseEvent( uMsg
2497 ,nX
2498 ,nY
8d902dd6 2499 ,(WXUINT)SHORT2FROMMP(lParam)
430974f8
DW
2500 );
2501 }
cdf1e714
DW
2502 }
2503 break;
430974f8 2504
cdf1e714 2505 case WM_SYSCOMMAND:
61243a51 2506 bProcessed = HandleSysCommand(wParam, lParam);
cdf1e714
DW
2507 break;
2508
2509 case WM_COMMAND:
2510 {
2511 WORD id, cmd;
2512 WXHWND hwnd;
2513 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2514
61243a51 2515 bProcessed = HandleCommand(id, cmd, hwnd);
cdf1e714
DW
2516 }
2517 break;
2518
61243a51
DW
2519 //
2520 // For these messages we must return TRUE if process the message
2521 //
cdf1e714
DW
2522 case WM_DRAWITEM:
2523 case WM_MEASUREITEM:
2524 {
45bedfdd 2525 int nIdCtrl = (UINT)wParam;
45bedfdd 2526
61243a51 2527 if ( uMsg == WM_DRAWITEM )
cdf1e714 2528 {
45bedfdd 2529 bProcessed = OS2OnDrawItem(nIdCtrl,
cdf1e714
DW
2530 (WXDRAWITEMSTRUCT *)lParam);
2531 }
2532 else
2533 {
f5ea767e
DW
2534 return MRFROMLONG(OS2OnMeasureItem( nIdCtrl
2535 ,(WXMEASUREITEMSTRUCT *)lParam
2536 ));
cdf1e714
DW
2537 }
2538
61243a51 2539 if ( bProcessed )
e604d44b 2540 mResult = (MRESULT)TRUE;
cdf1e714
DW
2541 }
2542 break;
2543
61243a51 2544 case WM_QUERYDLGCODE:
47df2b8c 2545 if (!IsOfStandardClass())
cdf1e714 2546 {
47df2b8c
DW
2547 if ( m_lDlgCode )
2548 {
2549 mResult = (MRESULT)m_lDlgCode;
77f4f0a7 2550 bProcessed = true;
47df2b8c 2551 }
cdf1e714 2552 }
61243a51 2553 //
cdf1e714 2554 //else: get the dlg code from the DefWindowProc()
61243a51 2555 //
cdf1e714
DW
2556 break;
2557
61243a51
DW
2558 //
2559 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2560 // and key-down events are obtained from the WM_CHAR params.
2561 //
2562 case WM_CHAR:
cdf1e714 2563 {
61243a51 2564 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 2565
61243a51
DW
2566 if (uKeyFlags & KC_KEYUP)
2567 {
19193a2c 2568 //TODO: check if the cast to WXWORD isn't causing trouble
a086de98 2569 bProcessed = HandleKeyUp(wParam, lParam);
cdf1e714 2570 break;
61243a51
DW
2571 }
2572 else // keydown event
2573 {
77f4f0a7 2574 m_bLastKeydownProcessed = false;
61243a51
DW
2575 //
2576 // If this has been processed by an event handler,
2577 // return 0 now (we've handled it). DON't RETURN
2578 // we still need to process further
2579 //
a086de98 2580 m_bLastKeydownProcessed = HandleKeyDown(wParam, lParam);
61243a51 2581 if (uKeyFlags & KC_VIRTUALKEY)
cdf1e714 2582 {
61243a51
DW
2583 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2584
2585 //
2586 // We consider these message "not interesting" to OnChar
2587 //
61243a51
DW
2588 switch(uVk)
2589 {
a086de98
DW
2590 case VK_SHIFT:
2591 case VK_CTRL:
2592 case VK_MENU:
2593 case VK_CAPSLOCK:
2594 case VK_NUMLOCK:
2595 case VK_SCRLLOCK:
77f4f0a7 2596 bProcessed = true;
a086de98
DW
2597 break;
2598
61243a51
DW
2599 // Avoid duplicate messages to OnChar for these ASCII keys: they
2600 // will be translated by TranslateMessage() and received in WM_CHAR
2601 case VK_ESC:
61243a51
DW
2602 case VK_ENTER:
2603 case VK_BACKSPACE:
2604 case VK_TAB:
77f4f0a7 2605 // But set processed to false, not true to still pass them to
61243a51
DW
2606 // the control's default window proc - otherwise built-in
2607 // keyboard handling won't work
77f4f0a7 2608 bProcessed = false;
61243a51
DW
2609 break;
2610
61243a51 2611 default:
598d8cac 2612 bProcessed = HandleChar(wParam, lParam);
61243a51
DW
2613 }
2614 break;
cdf1e714 2615 }
61243a51
DW
2616 else // WM_CHAR -- Always an ASCII character
2617 {
a086de98
DW
2618 if (m_bLastKeydownProcessed)
2619 {
2620 //
2621 // The key was handled in the EVT_KEY_DOWN and handling
2622 // a key in an EVT_KEY_DOWN handler is meant, by
2623 // design, to prevent EVT_CHARs from happening
2624 //
77f4f0a7
WS
2625 m_bLastKeydownProcessed = false;
2626 bProcessed = true;
a086de98
DW
2627 }
2628 else // do generate a CHAR event
2629 {
77f4f0a7 2630 bProcessed = HandleChar(wParam, lParam, true);
a086de98
DW
2631 break;
2632 }
61243a51
DW
2633 }
2634 }
cdf1e714 2635 }
cdf1e714
DW
2636
2637 case WM_HSCROLL:
2638 case WM_VSCROLL:
2639 {
61243a51
DW
2640 WXWORD wCode;
2641 WXWORD wPos;
2642 WXHWND hWnd;
2643 UnpackScroll( wParam
2644 ,lParam
2645 ,&wCode
2646 ,&wPos
2647 ,&hWnd
2648 );
2649
2650 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2651 : wxVERTICAL
2652 ,wCode
2653 ,wPos
2654 ,hWnd
2655 );
cdf1e714
DW
2656 }
2657 break;
2658
3c299c3a
DW
2659 case WM_CONTROL:
2660 switch(SHORT2FROMMP(wParam))
2661 {
a5799260
DW
2662 case BN_PAINT:
2663 {
2664 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2665 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2666
2667 if (!pWin)
2668 {
77f4f0a7 2669 bProcessed = false;
a5799260
DW
2670 break;
2671 }
2672 if (pWin->IsKindOf(CLASSINFO(wxBitmapButton)))
2673 {
2674 wxBitmapButton* pBitmapButton = wxDynamicCast(pWin, wxBitmapButton);
2675
2676 pBitmapButton->OS2OnDraw((WXDRAWITEMSTRUCT *)lParam);
2677 }
2678 return 0;
2679 }
6670f564 2680 // break;
a5799260 2681
1de4baa3
DW
2682 case BKN_PAGESELECTEDPENDING:
2683 {
2684 PPAGESELECTNOTIFY pPage = (PPAGESELECTNOTIFY)lParam;
2685
2686 if ((pPage->ulPageIdNew != pPage->ulPageIdCur) &&
2687 (pPage->ulPageIdNew > 0L && pPage->ulPageIdCur > 0L))
2688 {
2689 wxWindowOS2* pWin = wxFindWinFromHandle(pPage->hwndBook);
2690 wxNotebookEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
2691 ,(int)SHORT1FROMMP(wParam)
2692 ,(int)pPage->ulPageIdNew
2693 ,(int)pPage->ulPageIdCur
2694 );
2695 if (!pWin)
2696 {
77f4f0a7 2697 bProcessed = false;
1de4baa3
DW
2698 break;
2699 }
2700 if (pWin->IsKindOf(CLASSINFO(wxNotebook)))
2701 {
2702 wxNotebook* pNotebook = wxDynamicCast(pWin, wxNotebook);
2703
2704 vEvent.SetEventObject(pWin);
2705 pNotebook->OnSelChange(vEvent);
77f4f0a7 2706 bProcessed = true;
1de4baa3
DW
2707 }
2708 else
77f4f0a7 2709 bProcessed = false;
1de4baa3
DW
2710 }
2711 else
77f4f0a7 2712 bProcessed = false;
1de4baa3
DW
2713 }
2714 break;
2715
2716 case BN_CLICKED: // Dups as LN_SELECT and CBN_LBSELECT
f289196b
DW
2717 {
2718 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2719 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2720
2721 if (!pWin)
2722 {
77f4f0a7 2723 bProcessed = false;
f289196b
DW
2724 break;
2725 }
2726 //
77ffb593 2727 // Simulate a WM_COMMAND here, as wxWidgets expects all control
f289196b
DW
2728 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2729 //
2730 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
2731 {
2732 wxRadioBox* pRadioBox = wxDynamicCast(pWin, wxRadioBox);
2733
2734 pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2735 ,(WXWORD)SHORT1FROMMP(wParam)
f289196b
DW
2736 );
2737 }
2738 if (pWin->IsKindOf(CLASSINFO(wxRadioButton)))
2739 {
2740 wxRadioButton* pRadioButton = wxDynamicCast(pWin, wxRadioButton);
2741
2742 pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2743 ,(WXWORD)SHORT1FROMMP(wParam)
f289196b
DW
2744 );
2745 }
2746 if (pWin->IsKindOf(CLASSINFO(wxCheckBox)))
2747 {
2748 wxCheckBox* pCheckBox = wxDynamicCast(pWin, wxCheckBox);
2749
2750 pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2751 ,(WXWORD)SHORT1FROMMP(wParam)
f289196b
DW
2752 );
2753 }
1de4baa3
DW
2754 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2755 {
2756 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2757
2758 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2759 ,(WXWORD)SHORT1FROMMP(wParam)
1de4baa3
DW
2760 );
2761 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2762 Refresh();
2763 }
2764 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2765 {
2766 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2767
2768 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2769 ,(WXWORD)SHORT1FROMMP(wParam)
1de4baa3
DW
2770 );
2771 }
2772 return 0;
2773 }
6670f564 2774 // break;
1de4baa3
DW
2775
2776 case LN_ENTER: /* dups as CBN_EFCHANGE */
2777 {
2778 HWND hWnd = HWNDFROMMP(lParam);
2779 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2780
2781 if (!pWin)
2782 {
77f4f0a7 2783 bProcessed = false;
1de4baa3
DW
2784 break;
2785 }
2786 //
77ffb593 2787 // Simulate a WM_COMMAND here, as wxWidgets expects all control
1de4baa3
DW
2788 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2789 //
2790 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2791 {
2792 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2793
2794 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2795 ,(WXWORD)SHORT1FROMMP(wParam)
1de4baa3
DW
2796 );
2797 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2798 Refresh();
2799
2800 }
2801 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2802 {
2803 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2804
2805 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
6670f564 2806 ,(WXWORD)SHORT1FROMMP(wParam)
1de4baa3
DW
2807 );
2808 }
f289196b
DW
2809 return 0;
2810 }
6670f564 2811 // break;
f289196b 2812
3c299c3a
DW
2813 case SPBN_UPARROW:
2814 case SPBN_DOWNARROW:
2815 case SPBN_CHANGE:
2816 {
6670f564
WS
2817 char zVal[10];
2818 long lVal;
3c299c3a
DW
2819
2820 ::WinSendMsg( HWNDFROMMP(lParam)
2821 ,SPBM_QUERYVALUE
6670f564 2822 ,&zVal[0]
3c299c3a
DW
2823 ,MPFROM2SHORT( (USHORT)10
2824 ,(USHORT)SPBQ_UPDATEIFVALID
2825 )
2826 );
2827 lVal = atol(zVal);
2828 bProcessed = OS2OnScroll( wxVERTICAL
6670f564
WS
2829 ,(WXWORD)SHORT2FROMMP(wParam)
2830 ,(WXWORD)lVal
3c299c3a
DW
2831 ,HWNDFROMMP(lParam)
2832 );
2833 }
2834 break;
2835
2836 case SLN_SLIDERTRACK:
2837 {
6670f564
WS
2838 HWND hWnd = ::WinWindowFromID(GetHWND(), SHORT1FROMMP(wParam));
2839 wxWindowOS2* pChild = wxFindWinFromHandle(hWnd);
3c299c3a 2840
b389a12d
DW
2841 if (!pChild)
2842 {
77f4f0a7 2843 bProcessed = false;
b389a12d
DW
2844 break;
2845 }
3c299c3a
DW
2846 if (pChild->IsKindOf(CLASSINFO(wxSlider)))
2847 bProcessed = OS2OnScroll( wxVERTICAL
6670f564
WS
2848 ,(WXWORD)SHORT2FROMMP(wParam)
2849 ,(WXWORD)LONGFROMMP(lParam)
3c299c3a
DW
2850 ,hWnd
2851 );
2852 }
2853 break;
2854 }
2855 break;
2856
61243a51
DW
2857#if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2858 case WM_CTLCOLORCHANGE:
cdf1e714 2859 {
e604d44b 2860 bProcessed = HandleCtlColor(&hBrush);
61243a51
DW
2861 }
2862 break;
2863#endif
8d854fa9
DW
2864 case WM_ERASEBACKGROUND:
2865 //
2866 // Returning TRUE to requestw PM to paint the window background
2867 // in SYSCLR_WINDOW. We don't really want that
2868 //
2869 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2870 mResult = (MRESULT)(FALSE);
2871 break;
2872
cdf1e714
DW
2873 // the return value for this message is ignored
2874 case WM_SYSCOLORCHANGE:
61243a51 2875 bProcessed = HandleSysColorChange();
cdf1e714
DW
2876 break;
2877
61243a51
DW
2878 case WM_REALIZEPALETTE:
2879 bProcessed = HandlePaletteChanged();
cdf1e714
DW
2880 break;
2881
61243a51
DW
2882 // move all drag and drops to wxDrg
2883 case WM_ENDDRAG:
2884 bProcessed = HandleEndDrag(wParam);
cdf1e714
DW
2885 break;
2886
61243a51
DW
2887 case WM_INITDLG:
2888 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
cdf1e714 2889
61243a51 2890 if ( bProcessed )
cdf1e714
DW
2891 {
2892 // we never set focus from here
272ebf16 2893 mResult = (MRESULT)FALSE;
cdf1e714
DW
2894 }
2895 break;
2896
61243a51
DW
2897 // wxFrame specific message
2898 case WM_MINMAXFRAME:
f6bcfd97 2899 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
cdf1e714
DW
2900 break;
2901
61243a51
DW
2902 case WM_SYSVALUECHANGED:
2903 // TODO: do something
e604d44b 2904 mResult = (MRESULT)TRUE;
cdf1e714
DW
2905 break;
2906
61243a51
DW
2907 //
2908 // Comparable to WM_SETPOINTER for windows, only for just controls
2909 //
2910 case WM_CONTROLPOINTER:
2911 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2912 ,(HWND)lParam // Cursor Handle
2913 );
2914 if (bProcessed )
cdf1e714 2915 {
61243a51
DW
2916 //
2917 // Returning TRUE stops the DefWindowProc() from further
cdf1e714
DW
2918 // processing this message - exactly what we need because we've
2919 // just set the cursor.
61243a51 2920 //
e604d44b 2921 mResult = (MRESULT)TRUE;
cdf1e714
DW
2922 }
2923 break;
c82be69b
JS
2924
2925#if wxUSE_MENUS_NATIVE
2926 case WM_MENUEND:
2927 if (wxCurrentPopupMenu)
2928 {
2929 if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
2930 {
2931 // Break out of msg loop in DoPopupMenu
2932 ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
2933 }
2934 }
2935 break;
2936#endif // wxUSE_MENUS_NATIVE
2937
cdf1e714 2938 }
61243a51 2939 if (!bProcessed)
cdf1e714
DW
2940 {
2941#ifdef __WXDEBUG__
2942 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
61243a51 2943 wxGetMessageName(uMsg));
cdf1e714 2944#endif // __WXDEBUG__
d08f23a7
DW
2945 if (IsKindOf(CLASSINFO(wxFrame)))
2946 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
1b086de1
DW
2947 else if (IsKindOf(CLASSINFO(wxDialog)))
2948 mResult = ::WinDefDlgProc( m_hWnd, uMsg, wParam, lParam);
d08f23a7
DW
2949 else
2950 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
cdf1e714 2951 }
e604d44b 2952 return mResult;
0367c1c0 2953} // end of wxWindowOS2::OS2WindowProc
cdf1e714 2954
2461cfa0
SN
2955// ----------------------------------------------------------------------------
2956// wxWindow <-> HWND map
2957// ----------------------------------------------------------------------------
2958
2959wxWinHashTable *wxWinHandleHash = NULL;
2960
61243a51
DW
2961wxWindow* wxFindWinFromHandle(
2962 WXHWND hWnd
2963)
cdf1e714 2964{
2461cfa0 2965 return (wxWindow *)wxWinHandleHash->Get((long)hWnd);
61243a51 2966} // end of wxFindWinFromHandle
cdf1e714 2967
61243a51
DW
2968void wxAssociateWinWithHandle(
2969 HWND hWnd
19193a2c 2970, wxWindowOS2* pWin
61243a51 2971)
cdf1e714 2972{
61243a51
DW
2973 //
2974 // Adding NULL hWnd is (first) surely a result of an error and
cdf1e714 2975 // (secondly) breaks menu command processing
61243a51 2976 //
cdf1e714
DW
2977 wxCHECK_RET( hWnd != (HWND)NULL,
2978 wxT("attempt to add a NULL hWnd to window list ignored") );
2979
2980
61243a51
DW
2981 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
2982
2983 if (pOldWin && (pOldWin != pWin))
cdf1e714 2984 {
61243a51 2985 wxString str(pWin->GetClassInfo()->GetClassName());
0fba44b4
DW
2986
2987 wxLogError( _T("Bug! Found existing HWND %X for new window of class %s")
61243a51 2988 ,(int)hWnd
0fba44b4 2989 ,str.c_str()
61243a51 2990 );
cdf1e714 2991 }
61243a51 2992 else if (!pOldWin)
cdf1e714 2993 {
2461cfa0
SN
2994 wxWinHandleHash->Put( (long)hWnd
2995 ,(wxWindow *)pWin
2996 );
cdf1e714 2997 }
61243a51 2998} // end of wxAssociateWinWithHandle
cdf1e714 2999
77f4f0a7 3000void wxRemoveHandleAssociation( wxWindowOS2* pWin )
cdf1e714 3001{
2461cfa0 3002 wxWinHandleHash->Delete((long)pWin->GetHWND());
61243a51 3003} // end of wxRemoveHandleAssociation
cdf1e714 3004
61243a51 3005//
cdf1e714
DW
3006// Default destroyer - override if you destroy it in some other way
3007// (e.g. with MDI child windows)
61243a51 3008//
0367c1c0 3009void wxWindowOS2::OS2DestroyWindow()
cdf1e714
DW
3010{
3011}
3012
77f4f0a7
WS
3013bool wxWindowOS2::OS2GetCreateWindowCoords( const wxPoint& rPos,
3014 const wxSize& rSize,
3015 int& rnX,
3016 int& rnY,
3017 int& rnWidth,
3018 int& rnHeight ) const
f9efbe3a 3019{
77f4f0a7
WS
3020 bool bNonDefault = false;
3021 static const int DEFAULT_Y = 200;
3022 static const int DEFAULT_H = 250;
f9efbe3a 3023
77f4f0a7 3024 if (rPos.x == wxDefaultCoord)
f9efbe3a 3025 {
f9efbe3a
DW
3026 rnX = rnY = CW_USEDEFAULT;
3027 }
3028 else
3029 {
3030 rnX = rPos.x;
77f4f0a7
WS
3031 rnY = rPos.y == wxDefaultCoord ? DEFAULT_Y : rPos.y;
3032 bNonDefault = true;
f9efbe3a 3033 }
77f4f0a7 3034 if (rSize.x == wxDefaultCoord)
f9efbe3a 3035 {
f9efbe3a
DW
3036 rnWidth = rnHeight = CW_USEDEFAULT;
3037 }
3038 else
3039 {
3040 rnWidth = rSize.x;
77f4f0a7
WS
3041 rnHeight = rSize.y == wxDefaultCoord ? DEFAULT_H : rSize.y;
3042 bNonDefault = true;
f9efbe3a
DW
3043 }
3044 return bNonDefault;
3045} // end of wxWindowOS2::OS2GetCreateWindowCoords
3046
6ed98c6a
DW
3047WXHWND wxWindowOS2::OS2GetParent() const
3048{
3049 return m_parent ? m_parent->GetHWND() : NULL;
3050}
3051
6670f564
WS
3052bool wxWindowOS2::OS2Create( PSZ zClass,
3053 const wxChar* zTitle,
3054 WXDWORD dwStyle,
3055 const wxPoint& rPos,
3056 const wxSize& rSize,
3057 void* pCtlData,
3058 WXDWORD WXUNUSED(dwExStyle),
3059 bool bIsChild )
61243a51 3060{
6670f564
WS
3061 ERRORID vError;
3062 wxString sError;
3063 int nX = 0L;
3064 int nY = 0L;
3065 int nWidth = 0L;
3066 int nHeight = 0L;
3067 long lControlId = 0L;
3068 wxWindowCreationHook vHook(this);
3069 wxString sClassName((wxChar*)zClass);
5d44b24e
DW
3070
3071 OS2GetCreateWindowCoords( rPos
3072 ,rSize
3073 ,nX
3074 ,nY
3075 ,nWidth
3076 ,nHeight
3077 );
3078
5d44b24e 3079 if (bIsChild)
cdf1e714 3080 {
5d44b24e
DW
3081 lControlId = GetId();
3082 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
cdf1e714 3083 {
5d44b24e 3084 dwStyle |= WS_CLIPSIBLINGS;
cdf1e714
DW
3085 }
3086 }
cd212ee4 3087 //
5d44b24e
DW
3088 // For each class "Foo" we have we also have "FooNR" ("no repaint") class
3089 // which is the same but without CS_[HV]REDRAW class styles so using it
3090 // ensures that the window is not fully repainted on each resize
e604d44b 3091 //
020172f6 3092 if (!HasFlag(wxFULL_REPAINT_ON_RESIZE))
51c1d535 3093 {
5d44b24e
DW
3094 sClassName += wxT("NR");
3095 }
6ed98c6a
DW
3096 m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
3097 ,(PSZ)sClassName.c_str()
0fba44b4 3098 ,(PSZ)(zTitle ? zTitle : wxEmptyString)
6ed98c6a
DW
3099 ,(ULONG)dwStyle
3100 ,(LONG)0L
3101 ,(LONG)0L
3102 ,(LONG)0L
3103 ,(LONG)0L
3104 ,NULLHANDLE
3105 ,HWND_TOP
3106 ,(ULONG)lControlId
3107 ,pCtlData
3108 ,NULL
3109 );
5d44b24e
DW
3110 if (!m_hWnd)
3111 {
3112 vError = ::WinGetLastError(wxGetInstance());
3113 sError = wxPMErrorToStr(vError);
77f4f0a7 3114 return false;
51c1d535 3115 }
5d44b24e 3116 SubclassWin(m_hWnd);
a756f210 3117 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
4a46a5df 3118
0fba44b4 3119 m_backgroundColour.Set(wxString(wxT("GREY")));
4a46a5df 3120
6670f564 3121 LONG lColor = (LONG)m_backgroundColour.GetPixel();
4a46a5df
DW
3122
3123 if (!::WinSetPresParam( m_hWnd
3124 ,PP_BACKGROUNDCOLOR
3125 ,sizeof(LONG)
3126 ,(PVOID)&lColor
3127 ))
3128 {
3129 vError = ::WinGetLastError(vHabmain);
3130 sError = wxPMErrorToStr(vError);
0fba44b4 3131 wxLogError(_T("Error creating frame. Error: %s\n"), sError.c_str());
77f4f0a7 3132 return false;
4a46a5df 3133 }
5d44b24e
DW
3134 SetSize( nX
3135 ,nY
3136 ,nWidth
3137 ,nHeight
3138 );
77f4f0a7 3139 return true;
5d44b24e 3140} // end of WinGuiBase_Window::OS2Create
cdf1e714
DW
3141
3142// ===========================================================================
3143// OS2 PM message handlers
3144// ===========================================================================
3145
3146// ---------------------------------------------------------------------------
61243a51 3147// window creation/destruction
cdf1e714
DW
3148// ---------------------------------------------------------------------------
3149
77f4f0a7
WS
3150bool wxWindowOS2::HandleCreate( WXLPCREATESTRUCT WXUNUSED(vCs),
3151 bool* pbMayCreate )
cdf1e714 3152{
19193a2c 3153 wxWindowCreateEvent vEvent((wxWindow*)this);
cdf1e714 3154
61243a51 3155 (void)GetEventHandler()->ProcessEvent(vEvent);
77f4f0a7
WS
3156 *pbMayCreate = true;
3157 return true;
0367c1c0 3158} // end of wxWindowOS2::HandleCreate
cdf1e714 3159
0367c1c0 3160bool wxWindowOS2::HandleDestroy()
cdf1e714 3161{
6e348b12
DW
3162 wxWindowDestroyEvent vEvent((wxWindow*)this);
3163 vEvent.SetId(GetId());
3164 (void)GetEventHandler()->ProcessEvent(vEvent);
61243a51
DW
3165
3166 //
3167 // Delete our drop target if we've got one
3168 //
cdf1e714 3169#if wxUSE_DRAG_AND_DROP
61243a51 3170 if (m_dropTarget != NULL)
cdf1e714 3171 {
cdf1e714
DW
3172 delete m_dropTarget;
3173 m_dropTarget = NULL;
3174 }
3175#endif // wxUSE_DRAG_AND_DROP
3176
61243a51 3177 //
cdf1e714 3178 // WM_DESTROY handled
61243a51 3179 //
77f4f0a7 3180 return true;
0367c1c0 3181} // end of wxWindowOS2::HandleDestroy
cdf1e714
DW
3182
3183// ---------------------------------------------------------------------------
3184// activation/focus
3185// ---------------------------------------------------------------------------
0367c1c0 3186void wxWindowOS2::OnSetFocus(
61243a51
DW
3187 wxFocusEvent& rEvent
3188)
cdf1e714 3189{
61243a51 3190 rEvent.Skip();
0367c1c0 3191} // end of wxWindowOS2::OnSetFocus
61243a51 3192
0367c1c0 3193bool wxWindowOS2::HandleActivate(
61243a51
DW
3194 int nState
3195, WXHWND WXUNUSED(hActivate)
3196)
3197{
3198 wxActivateEvent vEvent( wxEVT_ACTIVATE
3199 ,(bool)nState
3200 ,m_windowId
3201 );
3202 vEvent.SetEventObject(this);
3203 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3204} // end of wxWindowOS2::HandleActivate
61243a51 3205
77f4f0a7 3206bool wxWindowOS2::HandleSetFocus( WXHWND WXUNUSED(hWnd) )
cdf1e714 3207{
54ffa107
DW
3208 //
3209 // Notify the parent keeping track of focus for the kbd navigation
3210 // purposes that we got it
3211 //
3212 wxChildFocusEvent vEventFocus((wxWindow *)this);
3213 (void)GetEventHandler()->ProcessEvent(vEventFocus);
3214
cdf1e714 3215#if wxUSE_CARET
61243a51 3216 //
cdf1e714 3217 // Deal with caret
61243a51
DW
3218 //
3219 if (m_caret)
cdf1e714
DW
3220 {
3221 m_caret->OnSetFocus();
3222 }
3223#endif // wxUSE_CARET
3224
1bcfc0e1
DW
3225#if wxUSE_TEXTCTRL
3226 // If it's a wxTextCtrl don't send the event as it will be done
3227 // after the control gets to process it from EN_FOCUS handler
3228 if ( wxDynamicCastThis(wxTextCtrl) )
cdf1e714 3229 {
77f4f0a7 3230 return false;
cdf1e714 3231 }
1bcfc0e1 3232#endif // wxUSE_TEXTCTRL
cdf1e714 3233
61243a51 3234 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
cdf1e714 3235
61243a51
DW
3236 vEvent.SetEventObject(this);
3237 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3238} // end of wxWindowOS2::HandleSetFocus
cdf1e714 3239
77f4f0a7 3240bool wxWindowOS2::HandleKillFocus( WXHWND hWnd )
cdf1e714
DW
3241{
3242#if wxUSE_CARET
61243a51 3243 //
cdf1e714 3244 // Deal with caret
61243a51
DW
3245 //
3246 if (m_caret)
cdf1e714
DW
3247 {
3248 m_caret->OnKillFocus();
3249 }
3250#endif // wxUSE_CARET
3251
a23692f0 3252#if wxUSE_TEXTCTRL
f289196b 3253 //
a23692f0
DW
3254 // If it's a wxTextCtrl don't send the event as it will be done
3255 // after the control gets to process it.
3256 //
3257 wxTextCtrl* pCtrl = wxDynamicCastThis(wxTextCtrl);
3258
3259 if (pCtrl)
3260 {
77f4f0a7 3261 return false;
a23692f0
DW
3262 }
3263#endif
3264
f289196b 3265 //
a23692f0
DW
3266 // Don't send the event when in the process of being deleted. This can
3267 // only cause problems if the event handler tries to access the object.
3268 //
3269 if ( m_isBeingDeleted )
3270 {
77f4f0a7 3271 return false;
a23692f0
DW
3272 }
3273
61243a51
DW
3274 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
3275 ,m_windowId
3276 );
cdf1e714 3277
61243a51 3278 vEvent.SetEventObject(this);
a23692f0 3279
f289196b 3280 //
a23692f0
DW
3281 // wxFindWinFromHandle() may return NULL, it is ok
3282 //
3283 vEvent.SetWindow(wxFindWinFromHandle(hWnd));
61243a51 3284 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3285} // end of wxWindowOS2::HandleKillFocus
cdf1e714
DW
3286
3287// ---------------------------------------------------------------------------
3288// miscellaneous
3289// ---------------------------------------------------------------------------
3290
0367c1c0 3291bool wxWindowOS2::HandleShow(
61243a51 3292 bool bShow
19193a2c 3293, int WXUNUSED(nStatus)
61243a51 3294)
cdf1e714 3295{
19193a2c 3296 wxShowEvent vEvent(GetId(), bShow);
cdf1e714 3297
687706f5 3298 vEvent.SetEventObject(this);
61243a51 3299 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3300} // end of wxWindowOS2::HandleShow
cdf1e714 3301
77f4f0a7 3302bool wxWindowOS2::HandleInitDialog( WXHWND WXUNUSED(hWndFocus) )
cdf1e714 3303{
61243a51 3304 wxInitDialogEvent vEvent(GetId());
cdf1e714 3305
687706f5 3306 vEvent.SetEventObject(this);
61243a51 3307 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3308} // end of wxWindowOS2::HandleInitDialog
cdf1e714 3309
19193a2c 3310bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
cdf1e714 3311{
61243a51 3312 // TODO: We'll handle drag and drop later
77f4f0a7 3313 return false;
cdf1e714
DW
3314}
3315
77f4f0a7
WS
3316bool wxWindowOS2::HandleSetCursor( USHORT WXUNUSED(vId),
3317 WXHWND hPointer )
cdf1e714 3318{
61243a51
DW
3319 //
3320 // Under OS/2 PM this allows the pointer to be changed
3321 // as it passes over a control
3322 //
3323 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
77f4f0a7 3324 return true;
0367c1c0 3325} // end of wxWindowOS2::HandleSetCursor
cdf1e714
DW
3326
3327// ---------------------------------------------------------------------------
3328// owner drawn stuff
3329// ---------------------------------------------------------------------------
77f4f0a7
WS
3330bool wxWindowOS2::OS2OnDrawItem( int vId,
3331 WXDRAWITEMSTRUCT* pItemStruct )
cdf1e714 3332{
19193a2c 3333#if wxUSE_OWNER_DRAWN
402e2f7c 3334 wxDC vDc;
61243a51 3335
19193a2c 3336#if wxUSE_MENUS_NATIVE
61243a51 3337 //
402e2f7c 3338 // Is it a menu item?
61243a51 3339 //
402e2f7c
DW
3340 if (vId == 0)
3341 {
5afb9458
DW
3342 ERRORID vError;
3343 wxString sError;
402e2f7c 3344 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
23122f8c
DW
3345 wxFrame* pFrame = (wxFrame*)this;
3346 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
402e2f7c 3347 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
23122f8c
DW
3348 wxRect vRect( pMeasureStruct->rclItem.xLeft
3349 ,pMeasureStruct->rclItem.yBottom
3350 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3351 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3352 );
77f4f0a7
WS
3353 vDc.SetHDC( hDC, false );
3354 vDc.SetHPS( pMeasureStruct->hps );
5afb9458 3355 //
77ffb593 3356 // Load the wxWidgets Pallete and set to RGB mode
5afb9458
DW
3357 //
3358 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3359 ,0L
3360 ,LCOLF_CONSECRGB
3361 ,0L
3362 ,(LONG)wxTheColourDatabase->m_nSize
3363 ,(PLONG)wxTheColourDatabase->m_palTable
3364 ))
3365 {
3366 vError = ::WinGetLastError(vHabmain);
3367 sError = wxPMErrorToStr(vError);
0fba44b4 3368 wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
5afb9458
DW
3369 }
3370 //
3371 // Set the color table to RGB mode
3372 //
3373 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3374 ,0L
3375 ,LCOLF_RGB
3376 ,0L
3377 ,0L
3378 ,NULL
3379 ))
3380 {
3381 vError = ::WinGetLastError(vHabmain);
3382 sError = wxPMErrorToStr(vError);
0fba44b4 3383 wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
5afb9458 3384 }
cdf1e714 3385
23122f8c
DW
3386 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3387
77f4f0a7
WS
3388 int eAction = 0;
3389 int eStatus = 0;
cdf1e714 3390
402e2f7c 3391 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
23122f8c
DW
3392 {
3393 //
3394 // Entire Item needs to be redrawn (either it has reappeared from
3395 // behind another window or is being displayed for the first time
3396 //
402e2f7c 3397 eAction = wxOwnerDrawn::wxODDrawAll;
23122f8c
DW
3398
3399 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3400 {
3401 //
3402 // If it is currently selected we let the system handle it
3403 //
3404 eStatus |= wxOwnerDrawn::wxODSelected;
3405 }
3406 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3407 {
3408 //
3409 // If it is currently checked we draw our own
3410 //
3411 eStatus |= wxOwnerDrawn::wxODChecked;
3412 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3413 }
3414 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3415 {
3416 //
3417 // If it is currently disabled we let the system handle it
3418 //
3419 eStatus |= wxOwnerDrawn::wxODDisabled;
3420 }
3421 //
3422 // Don't really care about framed (indicationg focus) or NoDismiss
3423 //
3424 }
402e2f7c 3425 else
23122f8c 3426 {
5afb9458
DW
3427 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3428 {
3429 eAction = wxOwnerDrawn::wxODDrawAll;
3430 eStatus |= wxOwnerDrawn::wxODSelected;
3431 //
3432 // Keep the system from trying to highlight with its bogus colors
3433 //
3434 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3435 }
3436 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3437 {
3438 eAction = wxOwnerDrawn::wxODDrawAll;
3439 eStatus = 0;
3440 //
3441 // Keep the system from trying to highlight with its bogus colors
3442 //
3443 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3444 }
3445 else
3446 {
3447 //
3448 // For now we don't care about anything else
3449 // just ignore the entire message!
3450 //
77f4f0a7 3451 return true;
5afb9458 3452 }
23122f8c
DW
3453 }
3454 //
3455 // Now redraw the item
3456 //
45bedfdd
DW
3457 return(pMenuItem->OnDrawItem( vDc
3458 ,vRect
23122f8c
DW
3459 ,(wxOwnerDrawn::wxODAction)eAction
3460 ,(wxOwnerDrawn::wxODStatus)eStatus
45bedfdd 3461 ));
402e2f7c
DW
3462 //
3463 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3464 // the system will do the highlight or fraeming or disabling for us,
3465 // otherwise, we'd have to do it ourselves.
61243a51 3466 //
cdf1e714 3467 }
19193a2c 3468#endif // wxUSE_MENUS_NATIVE
cdf1e714 3469
402e2f7c
DW
3470 wxWindow* pItem = FindItem(vId);
3471
3472 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3473 {
3474 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3475 }
19193a2c
KB
3476#else
3477 vId = vId;
3478 pItemStruct = pItemStruct;
61243a51 3479#endif
77f4f0a7 3480 return false;
0367c1c0 3481} // end of wxWindowOS2::OS2OnDrawItem
cdf1e714 3482
77f4f0a7
WS
3483long wxWindowOS2::OS2OnMeasureItem( int lId,
3484 WXMEASUREITEMSTRUCT* pItemStruct )
0e320a79 3485{
19193a2c 3486#if wxUSE_OWNER_DRAWN
402e2f7c
DW
3487 //
3488 // Is it a menu item?
3489 //
45bedfdd 3490 if (lId == 65536) // I really don't like this...has to be a better indicator
cdf1e714 3491 {
4049cc1c 3492 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
45bedfdd 3493 {
4049cc1c
DW
3494 size_t nWidth;
3495 size_t nHeight;
3496 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
45bedfdd
DW
3497 wxFrame* pFrame = (wxFrame*)this;
3498 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
cdf1e714 3499
45bedfdd 3500 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
4049cc1c
DW
3501 nWidth = 0L;
3502 nHeight = 0L;
3503 if (pMenuItem->OnMeasureItem( &nWidth
3504 ,&nHeight
3505 ))
3506 {
f5ea767e
DW
3507 MRESULT mRc;
3508
4049cc1c
DW
3509 pMeasureStruct->rclItem.xRight = nWidth;
3510 pMeasureStruct->rclItem.xLeft = 0L;
3511 pMeasureStruct->rclItem.yTop = nHeight;
3512 pMeasureStruct->rclItem.yBottom = 0L;
f5ea767e
DW
3513 mRc = MRFROM2SHORT(nHeight, nWidth);
3514 return LONGFROMMR(mRc);
4049cc1c 3515 }
f5ea767e 3516 return 0L;
45bedfdd 3517 }
cdf1e714 3518 }
f15b4952 3519 wxWindow* pItem = FindItem(lId);
cdf1e714 3520
402e2f7c 3521 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
cdf1e714 3522 {
1de4baa3
DW
3523 OWNERITEM vItem;
3524
3525 vItem.idItem = (LONG)pItemStruct;
3526 return ((wxControl *)pItem)->OS2OnMeasure((WXMEASUREITEMSTRUCT*)&vItem);
cdf1e714 3527 }
19193a2c
KB
3528#else
3529 lId = lId;
3530 pItemStruct = pItemStruct;
3531#endif // wxUSE_OWNER_DRAWN
cdf1e714 3532 return FALSE;
0e320a79
DW
3533}
3534
cdf1e714
DW
3535// ---------------------------------------------------------------------------
3536// colours and palettes
3537// ---------------------------------------------------------------------------
849949b1 3538
0367c1c0 3539bool wxWindowOS2::HandleSysColorChange()
0e320a79 3540{
61243a51 3541 wxSysColourChangedEvent vEvent;
cdf1e714 3542
61243a51
DW
3543 vEvent.SetEventObject(this);
3544 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3545} // end of wxWindowOS2::HandleSysColorChange
0e320a79 3546
77f4f0a7 3547bool wxWindowOS2::HandleCtlColor( WXHBRUSH* WXUNUSED(phBrush) )
0e320a79 3548{
61243a51
DW
3549 //
3550 // Not much provided with message. So not sure I can do anything with it
3551 //
77f4f0a7 3552 return true;
0367c1c0 3553} // end of wxWindowOS2::HandleCtlColor
cdf1e714 3554
0e320a79 3555
cdf1e714 3556// Define for each class of dialog and control
19193a2c
KB
3557WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
3558 WXHWND WXUNUSED(hWnd),
3559 WXUINT WXUNUSED(nCtlColor),
3560 WXUINT WXUNUSED(message),
3561 WXWPARAM WXUNUSED(wParam),
3562 WXLPARAM WXUNUSED(lParam))
0e320a79 3563{
cdf1e714 3564 return (WXHBRUSH)0;
0e320a79
DW
3565}
3566
0367c1c0 3567bool wxWindowOS2::HandlePaletteChanged()
0e320a79 3568{
61243a51
DW
3569 // need to set this to something first
3570 WXHWND hWndPalChange = NULLHANDLE;
cdf1e714 3571
61243a51
DW
3572 wxPaletteChangedEvent vEvent(GetId());
3573
3574 vEvent.SetEventObject(this);
3575 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
0e320a79 3576
61243a51 3577 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3578} // end of wxWindowOS2::HandlePaletteChanged
61243a51 3579
61243a51 3580//
cdf1e714 3581// Responds to colour changes: passes event on to children.
61243a51 3582//
0367c1c0 3583void wxWindowOS2::OnSysColourChanged(
61243a51
DW
3584 wxSysColourChangedEvent& rEvent
3585)
0e320a79 3586{
2461cfa0 3587 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
61243a51 3588
2461cfa0 3589 while (node)
cdf1e714 3590 {
61243a51 3591 //
cdf1e714 3592 // Only propagate to non-top-level windows
61243a51 3593 //
2461cfa0 3594 wxWindow* pWin = (wxWindow *)node->GetData();
61243a51
DW
3595
3596 if (pWin->GetParent())
cdf1e714 3597 {
61243a51 3598 wxSysColourChangedEvent vEvent;
cdf1e714 3599
687706f5 3600 rEvent.SetEventObject(pWin);
61243a51
DW
3601 pWin->GetEventHandler()->ProcessEvent(vEvent);
3602 }
2461cfa0 3603 node = node->GetNext();
cdf1e714 3604 }
0367c1c0 3605} // end of wxWindowOS2::OnSysColourChanged
0e320a79 3606
cdf1e714
DW
3607// ---------------------------------------------------------------------------
3608// painting
3609// ---------------------------------------------------------------------------
3610
b45bca40
DW
3611void wxWindow::OnPaint (
3612 wxPaintEvent& rEvent
3613)
3614{
3615 HDC hDC = (HDC)wxPaintDC::FindDCInCache((wxWindow*) rEvent.GetEventObject());
3616
3617 if (hDC != 0)
3618 {
3619 OS2DefWindowProc( (WXUINT)WM_PAINT
3620 ,(WXWPARAM)hDC
3621 ,(WXLPARAM)0
3622 );
3623 }
3624} // end of wxWindow::OnPaint
3625
0367c1c0 3626bool wxWindowOS2::HandlePaint()
0e320a79 3627{
19193a2c
KB
3628 HRGN hRgn;
3629 wxPaintEvent vEvent(m_windowId);
40bd6154 3630 HPS hPS;
19193a2c
KB
3631 bool bProcessed;
3632
3633 // Create empty region
3634 // TODO: get HPS somewhere else if possible
3635 hPS = ::WinGetPS(GetHwnd());
3636 hRgn = ::GpiCreateRegion(hPS, 0, NULL);
61243a51 3637
19193a2c 3638 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
61243a51 3639 {
2173b18f 3640 wxLogLastError(wxT("CreateRectRgn"));
77f4f0a7 3641 return false;
61243a51 3642 }
7e99520b 3643
5d826f60
SN
3644 // Get all the rectangles from the region, convert the individual
3645 // rectangles to "the other" coordinate system and reassemble a
3646 // region from the rectangles, to be feed into m_updateRegion.
3647 //
3648 // FIXME: This is a bad hack since OS/2 API specifies that rectangles
0a13502d
WS
3649 // passed into GpiSetRegion must not have Bottom > Top,
3650 // however, at first sight, it _seems_ to work nonetheless.
5d826f60
SN
3651 //
3652 RGNRECT vRgnData;
3653 PRECTL pUpdateRects = NULL;
3654 vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
3655 if (::GpiQueryRegionRects( hPS // Pres space
3656 ,hRgn // Handle of region to query
3657 ,NULL // Return all RECTs
3658 ,&vRgnData // Will contain number or RECTs in region
3659 ,NULL // NULL to return number of RECTs
3660 ))
3661 {
3662 pUpdateRects = new RECTL[vRgnData.crcReturned];
3663 vRgnData.crc = vRgnData.crcReturned;
3664 vRgnData.ircStart = 1;
3665 if (::GpiQueryRegionRects( hPS // Pres space of source
3666 ,hRgn // Handle of source region
3667 ,NULL // Return all RECTs
3668 ,&vRgnData // Operations set to return rects
3669 ,pUpdateRects // Will contain the actual RECTS
3670 ))
3671 {
3672 int height;
3673 RECT vRect;
3674 ::WinQueryWindowRect(GetHwnd(), &vRect);
3675 height = vRect.yTop;
3676
3677 for(size_t i = 0; i < vRgnData.crc; i++)
3678 {
3679 int rectHeight;
3680 rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
3681 pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
3682 pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
3683 }
3684 ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
3685 delete [] pUpdateRects;
3686 }
3687 }
3688
19193a2c
KB
3689 m_updateRegion = wxRegion(hRgn, hPS);
3690
61243a51 3691 vEvent.SetEventObject(this);
19193a2c
KB
3692 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
3693
524d72c4
DW
3694 if (!bProcessed &&
3695 IsKindOf(CLASSINFO(wxPanel)) &&
3696 GetChildren().GetCount() == 0
3697 )
3698 {
3699 //
3700 // OS/2 needs to process this right here, not by the default proc
f289196b
DW
3701 // Window's default proc correctly paints everything, OS/2 does not.
3702 // For decorative panels that typically have no children, we draw
3703 // borders.
524d72c4
DW
3704 //
3705 HPS hPS;
3706 RECTL vRect;
524d72c4
DW
3707
3708 hPS = ::WinBeginPaint( GetHwnd()
3709 ,NULLHANDLE
3710 ,&vRect
3711 );
3712 if(hPS)
3713 {
3714 ::GpiCreateLogColorTable( hPS
3715 ,0L
3716 ,LCOLF_CONSECRGB
3717 ,0L
3718 ,(LONG)wxTheColourDatabase->m_nSize
3719 ,(PLONG)wxTheColourDatabase->m_palTable
3720 );
3721 ::GpiCreateLogColorTable( hPS
3722 ,0L
3723 ,LCOLF_RGB
3724 ,0L
3725 ,0L
3726 ,NULL
3727 );
1de4baa3 3728 if (::WinIsWindowVisible(GetHWND()))
f289196b 3729 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
1de4baa3
DW
3730 if (m_dwExStyle)
3731 {
3732 LINEBUNDLE vLineBundle;
3733
3734 vLineBundle.lColor = 0x00000000; // Black
3735 vLineBundle.usMixMode = FM_OVERPAINT;
3736 vLineBundle.fxWidth = 1;
3737 vLineBundle.lGeomWidth = 1;
3738 vLineBundle.usType = LINETYPE_SOLID;
3739 vLineBundle.usEnd = 0;
3740 vLineBundle.usJoin = 0;
3741 ::GpiSetAttrs( hPS
3742 ,PRIM_LINE
3743 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
3744 ,0L
3745 ,&vLineBundle
3746 );
3747 ::WinQueryWindowRect(GetHwnd(), &vRect);
3748 wxDrawBorder( hPS
3749 ,vRect
3750 ,m_dwExStyle
3751 );
524d72c4 3752 }
524d72c4 3753 }
f289196b 3754 ::WinEndPaint(hPS);
77f4f0a7 3755 bProcessed = true;
524d72c4 3756 }
f289196b
DW
3757 else if (!bProcessed &&
3758 IsKindOf(CLASSINFO(wxPanel))
3759 )
3760 {
3761 //
3762 // Panel with children, usually fills a frame client so no borders.
3763 //
77f4f0a7
WS
3764 HPS hPS;
3765 RECTL vRect;
524d72c4 3766
f289196b
DW
3767 hPS = ::WinBeginPaint( GetHwnd()
3768 ,NULLHANDLE
3769 ,&vRect
3770 );
3771 if(hPS)
3772 {
3773 ::GpiCreateLogColorTable( hPS
3774 ,0L
3775 ,LCOLF_CONSECRGB
3776 ,0L
3777 ,(LONG)wxTheColourDatabase->m_nSize
3778 ,(PLONG)wxTheColourDatabase->m_palTable
3779 );
3780 ::GpiCreateLogColorTable( hPS
3781 ,0L
3782 ,LCOLF_RGB
3783 ,0L
3784 ,0L
3785 ,NULL
3786 );
3787
1de4baa3 3788 if (::WinIsWindowVisible(GetHWND()))
f289196b
DW
3789 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3790 }
3791 ::WinEndPaint(hPS);
77f4f0a7 3792 bProcessed = true;
f289196b 3793 }
524d72c4 3794 return bProcessed;
0367c1c0 3795} // end of wxWindowOS2::HandlePaint
0e320a79 3796
77f4f0a7 3797bool wxWindowOS2::HandleEraseBkgnd( WXHDC hDC )
0e320a79 3798{
77f4f0a7
WS
3799 SWP vSwp;
3800 bool rc;
8d854fa9
DW
3801
3802 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3803 if (vSwp.fl & SWP_MINIMIZE)
77f4f0a7 3804 return true;
cdf1e714 3805
77f4f0a7 3806 wxDC vDC;
8d854fa9
DW
3807
3808 vDC.m_hPS = (HPS)hDC; // this is really a PS
19193a2c 3809 vDC.SetWindow((wxWindow*)this);
8d854fa9 3810 vDC.BeginDrawing();
cdf1e714 3811
77f4f0a7 3812 wxEraseEvent vEvent(m_windowId, &vDC);
8d854fa9
DW
3813
3814 vEvent.SetEventObject(this);
cdf1e714 3815
19193a2c 3816 rc = GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3817
8d854fa9
DW
3818 vDC.EndDrawing();
3819 vDC.m_hPS = NULLHANDLE;
77f4f0a7 3820 return true;
0367c1c0 3821} // end of wxWindowOS2::HandleEraseBkgnd
cdf1e714 3822
1a4138c7 3823void wxWindowOS2::OnEraseBackground(wxEraseEvent& rEvent)
0e320a79 3824{
1a4138c7
WS
3825 RECTL vRect;
3826 HPS hPS = rEvent.GetDC()->GetHPS();
3827 APIRET rc;
3828 LONG lColor = m_backgroundColour.GetPixel();
8d854fa9 3829
19193a2c
KB
3830 rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
3831 rc = ::WinFillRect(hPS, &vRect, lColor);
0367c1c0 3832} // end of wxWindowOS2::OnEraseBackground
0e320a79 3833
cdf1e714
DW
3834// ---------------------------------------------------------------------------
3835// moving and resizing
3836// ---------------------------------------------------------------------------
0e320a79 3837
0367c1c0 3838bool wxWindowOS2::HandleMinimize()
0e320a79 3839{
61243a51 3840 wxIconizeEvent vEvent(m_windowId);
cdf1e714 3841
61243a51
DW
3842 vEvent.SetEventObject(this);
3843 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3844} // end of wxWindowOS2::HandleMinimize
0e320a79 3845
0367c1c0 3846bool wxWindowOS2::HandleMaximize()
0e320a79 3847{
61243a51 3848 wxMaximizeEvent vEvent(m_windowId);
cdf1e714 3849
61243a51
DW
3850 vEvent.SetEventObject(this);
3851 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3852} // end of wxWindowOS2::HandleMaximize
0e320a79 3853
6670f564 3854bool wxWindowOS2::HandleMove( int nX, int nY )
0e320a79 3855{
6670f564
WS
3856 wxPoint pt(nX, nY);
3857 wxMoveEvent vEvent(pt, m_windowId);
cdf1e714 3858
61243a51
DW
3859 vEvent.SetEventObject(this);
3860 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3861} // end of wxWindowOS2::HandleMove
0e320a79 3862
6670f564
WS
3863bool wxWindowOS2::HandleSize( int nWidth,
3864 int nHeight,
3865 WXUINT WXUNUSED(nFlag) )
0e320a79 3866{
6670f564
WS
3867 wxSize sz(nWidth, nHeight);
3868 wxSizeEvent vEvent(sz, m_windowId);
cdf1e714 3869
61243a51
DW
3870 vEvent.SetEventObject(this);
3871 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3872} // end of wxWindowOS2::HandleSize
0e320a79 3873
6670f564 3874bool wxWindowOS2::HandleGetMinMaxInfo( PSWP pSwp )
0e320a79 3875{
61243a51 3876 POINTL vPoint;
cdf1e714 3877
61243a51 3878 switch(pSwp->fl)
cdf1e714 3879 {
61243a51 3880 case SWP_MAXIMIZE:
77f4f0a7
WS
3881#if !(defined(__WATCOMC__) && __WATCOMC__ < 1240 )
3882// Open Watcom 1.3 had incomplete headers
3883// that's reported and should be fixed for OW 1.4
61243a51
DW
3884 ::WinGetMaxPosition(GetHwnd(), pSwp);
3885 m_maxWidth = pSwp->cx;
3886 m_maxHeight = pSwp->cy;
6670f564 3887#endif
61243a51 3888 break;
cdf1e714 3889
61243a51 3890 case SWP_MINIMIZE:
77f4f0a7
WS
3891#if !(defined(__WATCOMC__) && __WATCOMC__ < 1240 )
3892// Open Watcom 1.3 had incomplete headers
3893// that's reported and should be fixed for OW 1.4
61243a51
DW
3894 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3895 m_minWidth = pSwp->cx;
3896 m_minHeight = pSwp->cy;
6670f564
WS
3897#else
3898 wxUnusedVar(vPoint);
3899#endif
61243a51 3900 break;
cdf1e714 3901
61243a51 3902 default:
6670f564 3903 return false;
cdf1e714 3904 }
6670f564 3905 return true;
0367c1c0 3906} // end of wxWindowOS2::HandleGetMinMaxInfo
0e320a79 3907
cdf1e714
DW
3908// ---------------------------------------------------------------------------
3909// command messages
3910// ---------------------------------------------------------------------------
77f4f0a7
WS
3911bool wxWindowOS2::HandleCommand( WXWORD wId,
3912 WXWORD wCmd,
3913 WXHWND hControl )
0e320a79 3914{
19193a2c 3915#if wxUSE_MENUS_NATIVE
61243a51 3916 if (wxCurrentPopupMenu)
0e320a79 3917 {
61243a51 3918 wxMenu* pPopupMenu = wxCurrentPopupMenu;
0e320a79 3919
61243a51
DW
3920 wxCurrentPopupMenu = NULL;
3921 return pPopupMenu->OS2Command(wCmd, wId);
cdf1e714 3922 }
19193a2c 3923#endif // wxUSE_MENUS_NATIVE
0e320a79 3924
61243a51
DW
3925 wxWindow* pWin = FindItem(wId);
3926
3927 if (!pWin)
cdf1e714 3928 {
61243a51 3929 pWin = wxFindWinFromHandle(hControl);
0e320a79 3930 }
cdf1e714 3931
61243a51 3932 if (pWin)
19193a2c
KB
3933 return pWin->OS2Command(wCmd, wId);
3934
77f4f0a7 3935 return false;
0367c1c0 3936} // end of wxWindowOS2::HandleCommand
de44a9f0 3937
77f4f0a7
WS
3938bool wxWindowOS2::HandleSysCommand( WXWPARAM wParam,
3939 WXLPARAM WXUNUSED(lParam) )
0e320a79 3940{
61243a51
DW
3941 //
3942 // 4 bits are reserved
3943 //
3944 switch (SHORT1FROMMP(wParam))
3945 {
3946 case SC_MAXIMIZE:
3947 return HandleMaximize();
3948
3949 case SC_MINIMIZE:
3950 return HandleMinimize();
3951 }
77f4f0a7 3952 return false;
0367c1c0 3953} // end of wxWindowOS2::HandleSysCommand
cdf1e714
DW
3954
3955// ---------------------------------------------------------------------------
3956// mouse events
3957// ---------------------------------------------------------------------------
19193a2c 3958//TODO!!! check against MSW
0367c1c0 3959void wxWindowOS2::InitMouseEvent(
61243a51
DW
3960 wxMouseEvent& rEvent
3961, int nX
3962, int nY
3963, WXUINT uFlags
3964)
cdf1e714 3965{
8d902dd6
SN
3966 int nHeight;
3967 DoGetSize(0, &nHeight);
61243a51 3968 rEvent.m_x = nX;
77ffb593 3969 // Convert to wxWidgets standard coordinate system!
8d902dd6
SN
3970 rEvent.m_y = nHeight - nY;
3971 rEvent.m_shiftDown = ((uFlags & KC_SHIFT) != 0);
3972 rEvent.m_controlDown = ((uFlags & KC_CTRL) != 0);
3973 rEvent.m_altDown = ((uFlags & KC_ALT) != 0);
3974 rEvent.m_leftDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
0a13502d 3975 0x8000) != 0;
8d902dd6 3976 rEvent.m_middleDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &
0a13502d 3977 0x8000) != 0;
8d902dd6 3978 rEvent.m_rightDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
0a13502d 3979 0x8000) != 0;
61243a51 3980 rEvent.SetTimestamp(s_currentMsg.time);
687706f5 3981 rEvent.SetEventObject(this);
6ed98c6a 3982 rEvent.SetId(GetId());
cdf1e714
DW
3983
3984#if wxUSE_MOUSEEVENT_HACK
61243a51
DW
3985 m_lastMouseX = nX;
3986 m_lastMouseY = nY;
3987 m_lastMouseEvent = rEvent.GetEventType();
cdf1e714 3988#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 3989} // end of wxWindowOS2::InitMouseEvent
0e320a79 3990
77f4f0a7
WS
3991bool wxWindowOS2::HandleMouseEvent( WXUINT uMsg,
3992 int nX,
3993 int nY,
3994 WXUINT uFlags )
0e320a79 3995{
77f4f0a7 3996 bool bProcessed = false;
b389a12d 3997
61243a51
DW
3998 //
3999 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
c82be69b 4000 // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
cdf1e714
DW
4001 // from the message id and take the value in the table to get wxWin event
4002 // id
61243a51 4003 //
cdf1e714
DW
4004 static const wxEventType eventsMouse[] =
4005 {
4006 wxEVT_MOTION,
4007 wxEVT_LEFT_DOWN,
4008 wxEVT_LEFT_UP,
4009 wxEVT_LEFT_DCLICK,
4010 wxEVT_RIGHT_DOWN,
4011 wxEVT_RIGHT_UP,
4012 wxEVT_RIGHT_DCLICK,
4013 wxEVT_MIDDLE_DOWN,
4014 wxEVT_MIDDLE_UP,
4015 wxEVT_MIDDLE_DCLICK
4016 };
4017
c82be69b
JS
4018 // Bounds check
4019 if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
b389a12d 4020 {
77f4f0a7 4021 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
b389a12d 4022
c82be69b
JS
4023 InitMouseEvent( vEvent
4024 ,nX
4025 ,nY
4026 ,uFlags
4027 );
4028
4029 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
4030 if (!bProcessed)
b389a12d 4031 {
77f4f0a7 4032 HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
c82be69b
JS
4033
4034 if (hCursor != NULLHANDLE)
4035 {
4036 ::WinSetPointer(HWND_DESKTOP, hCursor);
77f4f0a7 4037 bProcessed = true;
c82be69b 4038 }
b389a12d
DW
4039 }
4040 }
c82be69b 4041 return bProcessed;
0367c1c0 4042} // end of wxWindowOS2::HandleMouseEvent
61243a51 4043
77f4f0a7
WS
4044bool wxWindowOS2::HandleMouseMove( int nX,
4045 int nY,
4046 WXUINT uFlags )
0e320a79 4047{
61243a51 4048 if (!m_bMouseInWindow)
cdf1e714 4049 {
61243a51 4050 //
cdf1e714 4051 // Generate an ENTER event
61243a51 4052 //
77f4f0a7 4053 m_bMouseInWindow = true;
cdf1e714 4054
77f4f0a7 4055 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
cdf1e714 4056
61243a51
DW
4057 InitMouseEvent( vEvent
4058 ,nX
4059 ,nY
4060 ,uFlags
4061 );
cdf1e714 4062
61243a51 4063 (void)GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 4064 }
61243a51
DW
4065 return HandleMouseEvent( WM_MOUSEMOVE
4066 ,nX
4067 ,nY
4068 ,uFlags
4069 );
0367c1c0 4070} // end of wxWindowOS2::HandleMouseMove
0e320a79 4071
cdf1e714
DW
4072// ---------------------------------------------------------------------------
4073// keyboard handling
4074// ---------------------------------------------------------------------------
4075
61243a51
DW
4076//
4077// Create the key event of the given type for the given key - used by
4078// HandleChar and HandleKeyDown/Up
4079//
0367c1c0 4080wxKeyEvent wxWindowOS2::CreateKeyEvent(
61243a51
DW
4081 wxEventType eType
4082, int nId
4083, WXLPARAM lParam
a086de98 4084, WXWPARAM wParam
61243a51
DW
4085) const
4086{
4087 wxKeyEvent vEvent(eType);
4088
4089 vEvent.SetId(GetId());
4090 vEvent.m_shiftDown = IsShiftDown();
4091 vEvent.m_controlDown = IsCtrlDown();
4092 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
4093
687706f5 4094 vEvent.SetEventObject((wxWindow *)this); // const_cast
61243a51 4095 vEvent.m_keyCode = nId;
a086de98
DW
4096 vEvent.m_rawCode = (wxUint32)wParam;
4097 vEvent.m_rawFlags = (wxUint32)lParam;
61243a51
DW
4098 vEvent.SetTimestamp(s_currentMsg.time);
4099
4100 //
4101 // Translate the position to client coords
4102 //
4103 POINTL vPoint;
4104 RECTL vRect;
4105
4106 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
4107 ::WinQueryWindowRect( GetHwnd()
4108 ,&vRect
4109 );
4110
4111 vPoint.x -= vRect.xLeft;
4112 vPoint.y -= vRect.yBottom;
4113
4114 vEvent.m_x = vPoint.x;
4115 vEvent.m_y = vPoint.y;
4116
4117 return vEvent;
0367c1c0 4118} // end of wxWindowOS2::CreateKeyEvent
61243a51
DW
4119
4120//
6670f564 4121// isASCII is true only when we're called from WM_CHAR handler and not from
cdf1e714 4122// WM_KEYDOWN one
61243a51 4123//
6670f564
WS
4124bool wxWindowOS2::HandleChar( WXWPARAM WXUNUSED(wParam),
4125 WXLPARAM lParam,
4126 bool isASCII )
86de7616 4127{
77f4f0a7 4128 bool bCtrlDown = false;
6670f564 4129 int vId;
61243a51 4130
3437f881
DW
4131 if (m_bLastKeydownProcessed)
4132 {
4133 //
4134 // The key was handled in the EVT_KEY_DOWN. Handling a key in an
4135 // EVT_KEY_DOWN handler is meant, by design, to prevent EVT_CHARs
4136 // from happening, so just bail out at this point.
4137 //
6670f564
WS
4138 m_bLastKeydownProcessed = false;
4139 return true;
3437f881 4140 }
61243a51
DW
4141 if (isASCII)
4142 {
4143 //
a23692f0
DW
4144 // If 1 -> 26, translate to either special keycode or just set
4145 // ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
6670f564 4146 // ControlDown() == true.
61243a51 4147 //
1de4baa3 4148 vId = SHORT1FROMMP(lParam);
61243a51
DW
4149 if ((vId > 0) && (vId < 27))
4150 {
4151 switch (vId)
4152 {
4153 case 13:
4154 vId = WXK_RETURN;
4155 break;
4156
4157 case 8:
4158 vId = WXK_BACK;
4159 break;
4160
4161 case 9:
4162 vId = WXK_TAB;
4163 break;
4164
4165 default:
77f4f0a7 4166 bCtrlDown = true;
a23692f0 4167 break;
61243a51
DW
4168 }
4169 }
4170 }
a086de98 4171 else // we're called from WM_KEYDOWN
61243a51 4172 {
1de4baa3 4173 vId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
a086de98 4174 if (vId == 0)
6670f564 4175 return false;
61243a51
DW
4176 }
4177
6670f564 4178 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR, vId, lParam ));
61243a51 4179
a086de98
DW
4180 if (bCtrlDown)
4181 {
6670f564 4182 vEvent.m_controlDown = true;
61243a51 4183 }
6670f564 4184
a086de98 4185 return (GetEventHandler()->ProcessEvent(vEvent));
cdf1e714 4186}
86de7616 4187
77f4f0a7
WS
4188bool wxWindowOS2::HandleKeyDown( WXWPARAM wParam,
4189 WXLPARAM lParam )
cdf1e714 4190{
77f4f0a7 4191 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
86de7616 4192
61243a51
DW
4193 if (!nId)
4194 {
4195 //
4196 // Normal ASCII char
4197 //
1de4baa3 4198 nId = SHORT1FROMMP(lParam);
61243a51
DW
4199 }
4200
4201 if (nId != -1)
4202 {
77f4f0a7
WS
4203 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
4204 ,nId
4205 ,(MPARAM)lParam
4206 ,(MPARAM)wParam
4207 ));
61243a51
DW
4208
4209 if (GetEventHandler()->ProcessEvent(vEvent))
4210 {
77f4f0a7 4211 return true;
61243a51
DW
4212 }
4213 }
77f4f0a7 4214 return false;
0367c1c0 4215} // end of wxWindowOS2::HandleKeyDown
61243a51 4216
77f4f0a7
WS
4217bool wxWindowOS2::HandleKeyUp( WXWPARAM wParam,
4218 WXLPARAM lParam )
86de7616 4219{
77f4f0a7 4220 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
61243a51
DW
4221
4222 if (!nId)
4223 {
4224 //
4225 // Normal ASCII char
4226 //
3143083e 4227 nId = CHAR1FROMMP(lParam);
61243a51
DW
4228 }
4229
4230 if (nId != -1)
4231 {
77f4f0a7
WS
4232 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
4233 ,nId
4234 ,(MPARAM)lParam
4235 ,(MPARAM)wParam
4236 ));
61243a51
DW
4237
4238 if (GetEventHandler()->ProcessEvent(vEvent))
77f4f0a7 4239 return true;
61243a51 4240 }
77f4f0a7 4241 return false;
0367c1c0 4242} // end of wxWindowOS2::HandleKeyUp
86de7616 4243
cdf1e714
DW
4244// ---------------------------------------------------------------------------
4245// joystick
4246// ---------------------------------------------------------------------------
86de7616 4247
cdf1e714
DW
4248// ---------------------------------------------------------------------------
4249// scrolling
4250// ---------------------------------------------------------------------------
4251
77f4f0a7
WS
4252bool wxWindowOS2::OS2OnScroll( int nOrientation,
4253 WXWORD wParam,
4254 WXWORD wPos,
4255 WXHWND hControl )
cdf1e714 4256{
61243a51 4257 if (hControl)
86de7616 4258 {
61243a51
DW
4259 wxWindow* pChild = wxFindWinFromHandle(hControl);
4260
4261 if (pChild )
4262 return pChild->OS2OnScroll( nOrientation
4263 ,wParam
4264 ,wPos
4265 ,hControl
4266 );
cdf1e714 4267 }
86de7616 4268
61243a51
DW
4269 wxScrollWinEvent vEvent;
4270
4271 vEvent.SetPosition(wPos);
4272 vEvent.SetOrientation(nOrientation);
687706f5 4273 vEvent.SetEventObject(this);
61243a51
DW
4274
4275 switch (wParam)
4276 {
4277 case SB_LINEUP:
687706f5 4278 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEUP);
61243a51
DW
4279 break;
4280
4281 case SB_LINEDOWN:
687706f5 4282 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
61243a51
DW
4283 break;
4284
4285 case SB_PAGEUP:
687706f5 4286 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
61243a51
DW
4287 break;
4288
4289 case SB_PAGEDOWN:
687706f5 4290 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
61243a51
DW
4291 break;
4292
4293 case SB_SLIDERPOSITION:
687706f5 4294 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBRELEASE);
61243a51
DW
4295 break;
4296
4297 case SB_SLIDERTRACK:
687706f5 4298 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBTRACK);
61243a51
DW
4299 break;
4300
4301 default:
77f4f0a7 4302 return false;
61243a51
DW
4303 }
4304 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 4305} // end of wxWindowOS2::OS2OnScroll
86de7616 4306
d8a3f66c
DW
4307void wxWindowOS2::MoveChildren(
4308 int nDiff
4309)
4310{
5efff147
DW
4311 //
4312 // We want to handle top levels ourself, manually
4313 //
4314 if (!IsTopLevel() && GetAutoLayout())
d8a3f66c 4315 {
f289196b
DW
4316 Layout();
4317 }
4318 else
4319 {
4320 SWP vSwp;
d8a3f66c 4321
2461cfa0
SN
4322 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
4323 node;
4324 node = node->GetNext())
d8a3f66c 4325 {
2461cfa0 4326 wxWindow* pWin = node->GetData();
d8a3f66c 4327
f289196b
DW
4328 ::WinQueryWindowPos( GetHwndOf(pWin)
4329 ,&vSwp
4330 );
3bcf4cce
SN
4331 // Actually, only move children that already are placed on the
4332 // frame, not ones which are still at wxDefaultCoord.
4333 if (vSwp.y == wxDefaultCoord)
4334 continue;
f289196b
DW
4335 if (pWin->IsKindOf(CLASSINFO(wxControl)))
4336 {
4337 wxControl* pCtrl;
4338
4339 //
4340 // Must deal with controls that have margins like ENTRYFIELD. The SWP
4341 // struct of such a control will have and origin offset from its intended
4342 // position by the width of the margins.
4343 //
4344 pCtrl = wxDynamicCast(pWin, wxControl);
4345 vSwp.y -= pCtrl->GetYComp();
4346 vSwp.x -= pCtrl->GetXComp();
4347 }
4348 ::WinSetWindowPos( GetHwndOf(pWin)
4349 ,HWND_TOP
4350 ,vSwp.x
4351 ,vSwp.y - nDiff
4352 ,vSwp.cx
4353 ,vSwp.cy
52df30cf 4354 ,SWP_MOVE
f289196b
DW
4355 );
4356 ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
4357 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
4358 {
4359 wxRadioBox* pRadioBox;
4360
4361 pRadioBox = wxDynamicCast(pWin, wxRadioBox);
4362 pRadioBox->AdjustButtons( (int)vSwp.x
4363 ,(int)vSwp.y - nDiff
4364 ,(int)vSwp.cx
4365 ,(int)vSwp.cy
4366 ,pRadioBox->GetSizeFlags()
4367 );
4368 }
4369 if (pWin->IsKindOf(CLASSINFO(wxSlider)))
4370 {
4371 wxSlider* pSlider;
4372
4373 pSlider = wxDynamicCast(pWin, wxSlider);
4374 pSlider->AdjustSubControls( (int)vSwp.x
4375 ,(int)vSwp.y - nDiff
4376 ,(int)vSwp.cx
4377 ,(int)vSwp.cy
4378 ,(int)pSlider->GetSizeFlags()
4379 );
4380 }
d8a3f66c
DW
4381 }
4382 }
4a46a5df 4383 Refresh();
d8a3f66c
DW
4384} // end of wxWindowOS2::MoveChildren
4385
4386//
4387// Getting the Y position for a window, like a control, is a real
4388// pain. There are three sitatuions we must deal with in determining
77ffb593 4389// the OS2 to wxWidgets Y coordinate.
d8a3f66c
DW
4390//
4391// 1) The controls are created in a dialog.
4392// This is the easiest since a dialog is created with its original
4393// size so the standard: Y = ParentHeight - (Y + ControlHeight);
4394//
4395// 2) The controls are direct children of a frame
4396// In this instance the controls are actually children of the Frame's
4397// client. During creation the frame's client resizes several times
4398// during creation of the status bar and toolbars. The CFrame class
4399// will take care of this using its AlterChildPos proc.
4400//
4401// 3) The controls are children of a panel, which in turn is a child of
4402// a frame.
859e65de
DW
4403// The panel may be one of many, in which case the same treatment
4404// as 1 applies. It may be the only child, though.
d8a3f66c
DW
4405// This is the nastiest case. A panel is created as the only child of
4406// the frame and as such, when a frame has only one child, the child is
4407// expanded to fit the entire client area of the frame. Because the
4408// controls are created BEFORE this occurs their positions are totally
4409// whacked and any call to WinQueryWindowPos will return invalid
4410// coordinates. So for this situation we have to compare the size of
4411// the panel at control creation time with that of the frame client. If
4412// they are the same we can use the standard Y position equation. If
4413// not, then we must use the Frame Client's dimensions to position them
4414// as that will be the eventual size of the panel after the frame resizes
4415// it!
4416//
6670f564 4417int wxWindowOS2::GetOS2ParentHeight( wxWindowOS2* pParent )
d8a3f66c 4418{
d8a3f66c
DW
4419 //
4420 // Case 1
4421 //
4422 if (pParent->IsKindOf(CLASSINFO(wxDialog)))
e37db699 4423 return(pParent->GetClientSize().y);
d8a3f66c
DW
4424
4425 //
4426 // Case 2 -- if we are one of the separately built standard Frame
4427 // children, like a statusbar, menubar, or toolbar we want to
4428 // use the frame, itself, for positioning. Otherwise we are
4429 // child window and want to use the Frame's client.
4430 //
4431 else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
4432 {
4433 if (IsKindOf(CLASSINFO(wxStatusBar)) ||
4434 IsKindOf(CLASSINFO(wxMenuBar)) ||
4435 IsKindOf(CLASSINFO(wxToolBar))
4436 )
2590f154
DW
4437 {
4438 if (IsKindOf(CLASSINFO(wxToolBar)))
4439 {
4440 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
4441
4442 if (pFrame->GetToolBar() == this)
4443 return(pParent->GetSize().y);
4444 else
4445 return(pParent->GetClientSize().y);
4446 }
4447 else
4448 return(pParent->GetSize().y);
4449 }
d8a3f66c
DW
4450 else
4451 return(pParent->GetClientSize().y);
4452 }
d8a3f66c 4453 //
4a46a5df
DW
4454 // Case -- this is for any window that is the sole child of a Frame.
4455 // The grandparent must exist and it must be of type CFrame
4456 // and it's height must be different. Otherwise the standard
4457 // applies.
d8a3f66c 4458 //
6670f564
WS
4459 // else
4460 // {
4461
4462 return(pParent->GetClientSize().y);
4463
4464 // }
d8a3f66c
DW
4465} // end of wxWindowOS2::GetOS2ParentHeight
4466
45e0dc94
DW
4467//
4468// OS/2 needs a lot extra manipulation to deal with layouts
4469// for canvas windows, particularly scrolled ones.
4470//
06519806
DW
4471wxWindowCreationHook::wxWindowCreationHook(
4472 wxWindow* pWinBeingCreated
4473)
4474{
4475 gpWinBeingCreated = pWinBeingCreated;
4476} // end of wxWindowCreationHook::wxWindowCreationHook
4477
4478wxWindowCreationHook::~wxWindowCreationHook()
4479{
4480 gpWinBeingCreated = NULL;
4481} // end of wxWindowCreationHook::~wxWindowCreationHook
4482
cdf1e714
DW
4483// ===========================================================================
4484// global functions
4485// ===========================================================================
4486
61243a51 4487void wxGetCharSize(
987da0d4
DW
4488 WXHWND hWnd
4489, int* pX
4490, int* pY
19193a2c 4491,wxFont* WXUNUSED(pTheFont)
61243a51 4492)
cdf1e714 4493{
987da0d4
DW
4494 FONTMETRICS vFM;
4495 HPS hPS;
4496 BOOL rc;
4497
4498 hPS =::WinGetPS(hWnd);
4499
4500 rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
4501 if (rc)
4502 {
4503 if (pX)
4504 *pX = vFM.lAveCharWidth;
4505 if (pY)
4506 *pY = vFM.lEmHeight + vFM.lExternalLeading;
4507 }
4508 else
4509 {
4510 if (pX)
4511 *pX = 10;
4512 if (pY)
4513 *pY = 15;
4514 }
4515 ::WinReleasePS(hPS);
61243a51 4516} // end of wxGetCharSize
cdf1e714 4517
61243a51 4518//
cdf1e714
DW
4519// Returns 0 if was a normal ASCII value, not a special key. This indicates that
4520// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
61243a51
DW
4521//
4522int wxCharCodeOS2ToWX(
4523 int nKeySym
4524)
cdf1e714 4525{
61243a51
DW
4526 int nId = 0;
4527
4528 switch (nKeySym)
4529 {
4530 case VK_BACKTAB: nId = WXK_BACK; break;
4531 case VK_TAB: nId = WXK_TAB; break;
4532 case VK_CLEAR: nId = WXK_CLEAR; break;
4533 case VK_ENTER: nId = WXK_RETURN; break;
4534 case VK_SHIFT: nId = WXK_SHIFT; break;
4535 case VK_CTRL: nId = WXK_CONTROL; break;
4536 case VK_PAUSE: nId = WXK_PAUSE; break;
4537 case VK_SPACE: nId = WXK_SPACE; break;
3143083e
SN
4538 case VK_PAGEUP: nId = WXK_PRIOR; break;
4539 case VK_PAGEDOWN: nId = WXK_NEXT; break;
61243a51
DW
4540 case VK_ESC: nId = WXK_ESCAPE; break;
4541 case VK_END: nId = WXK_END; break;
4542 case VK_HOME : nId = WXK_HOME; break;
4543 case VK_LEFT : nId = WXK_LEFT; break;
4544 case VK_UP: nId = WXK_UP; break;
4545 case VK_RIGHT: nId = WXK_RIGHT; break;
4546 case VK_DOWN : nId = WXK_DOWN; break;
4547 case VK_PRINTSCRN: nId = WXK_PRINT; break;
4548 case VK_INSERT: nId = WXK_INSERT; break;
4549 case VK_DELETE: nId = WXK_DELETE; break;
a086de98 4550 case VK_CAPSLOCK: nId = WXK_CAPITAL; break;
61243a51
DW
4551 case VK_F1: nId = WXK_F1; break;
4552 case VK_F2: nId = WXK_F2; break;
4553 case VK_F3: nId = WXK_F3; break;
4554 case VK_F4: nId = WXK_F4; break;
4555 case VK_F5: nId = WXK_F5; break;
4556 case VK_F6: nId = WXK_F6; break;
4557 case VK_F7: nId = WXK_F7; break;
4558 case VK_F8: nId = WXK_F8; break;
4559 case VK_F9: nId = WXK_F9; break;
4560 case VK_F10: nId = WXK_F10; break;
4561 case VK_F11: nId = WXK_F11; break;
4562 case VK_F12: nId = WXK_F12; break;
4563 case VK_F13: nId = WXK_F13; break;
4564 case VK_F14: nId = WXK_F14; break;
4565 case VK_F15: nId = WXK_F15; break;
4566 case VK_F16: nId = WXK_F16; break;
4567 case VK_F17: nId = WXK_F17; break;
4568 case VK_F18: nId = WXK_F18; break;
4569 case VK_F19: nId = WXK_F19; break;
4570 case VK_F20: nId = WXK_F20; break;
4571 case VK_F21: nId = WXK_F21; break;
4572 case VK_F22: nId = WXK_F22; break;
4573 case VK_F23: nId = WXK_F23; break;
4574 case VK_F24: nId = WXK_F24; break;
a086de98
DW
4575 case VK_OEM_1: nId = ';'; break;
4576 case VK_OEM_PLUS: nId = '+'; break;
4577 case VK_OEM_COMMA: nId = ','; break;
4578 case VK_OEM_MINUS: nId = '-'; break;
4579 case VK_OEM_PERIOD: nId = '.'; break;
4580 case VK_OEM_2: nId = '/'; break;
4581 case VK_OEM_3: nId = '~'; break;
4582 case VK_OEM_4: nId = '['; break;
4583 case VK_OEM_5: nId = '\\'; break;
4584 case VK_OEM_6: nId = ']'; break;
4585 case VK_OEM_7: nId = '\''; break;
61243a51
DW
4586 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
4587 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
4588 default:
86de7616 4589 {
cdf1e714 4590 return 0;
86de7616
DW
4591 }
4592 }
61243a51
DW
4593 return nId;
4594} // end of wxCharCodeOS2ToWX
86de7616 4595
77f4f0a7
WS
4596int wxCharCodeWXToOS2( int nId,
4597 bool* bIsVirtual)
86de7616 4598{
77f4f0a7 4599 int nKeySym = 0;
61243a51 4600
77f4f0a7 4601 *bIsVirtual = true;
61243a51
DW
4602 switch (nId)
4603 {
4604 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
4605 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
4606 case WXK_CONTROL: nKeySym = VK_CTRL; break;
4607 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
3143083e
SN
4608 case WXK_PRIOR: nKeySym = VK_PAGEUP; break;
4609 case WXK_NEXT : nKeySym = VK_PAGEDOWN; break;
61243a51
DW
4610 case WXK_END: nKeySym = VK_END; break;
4611 case WXK_HOME : nKeySym = VK_HOME; break;
4612 case WXK_LEFT : nKeySym = VK_LEFT; break;
4613 case WXK_UP: nKeySym = VK_UP; break;
4614 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
4615 case WXK_DOWN : nKeySym = VK_DOWN; break;
4616 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
4617 case WXK_INSERT: nKeySym = VK_INSERT; break;
4618 case WXK_DELETE: nKeySym = VK_DELETE; break;
4619 case WXK_F1: nKeySym = VK_F1; break;
4620 case WXK_F2: nKeySym = VK_F2; break;
4621 case WXK_F3: nKeySym = VK_F3; break;
4622 case WXK_F4: nKeySym = VK_F4; break;
4623 case WXK_F5: nKeySym = VK_F5; break;
4624 case WXK_F6: nKeySym = VK_F6; break;
4625 case WXK_F7: nKeySym = VK_F7; break;
4626 case WXK_F8: nKeySym = VK_F8; break;
4627 case WXK_F9: nKeySym = VK_F9; break;
4628 case WXK_F10: nKeySym = VK_F10; break;
4629 case WXK_F11: nKeySym = VK_F11; break;
4630 case WXK_F12: nKeySym = VK_F12; break;
4631 case WXK_F13: nKeySym = VK_F13; break;
4632 case WXK_F14: nKeySym = VK_F14; break;
4633 case WXK_F15: nKeySym = VK_F15; break;
4634 case WXK_F16: nKeySym = VK_F16; break;
4635 case WXK_F17: nKeySym = VK_F17; break;
4636 case WXK_F18: nKeySym = VK_F18; break;
4637 case WXK_F19: nKeySym = VK_F19; break;
4638 case WXK_F20: nKeySym = VK_F20; break;
4639 case WXK_F21: nKeySym = VK_F21; break;
4640 case WXK_F22: nKeySym = VK_F22; break;
4641 case WXK_F23: nKeySym = VK_F23; break;
4642 case WXK_F24: nKeySym = VK_F24; break;
4643 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
4644 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
4645 default:
cdf1e714 4646 {
77f4f0a7 4647 *bIsVirtual = false;
61243a51 4648 nKeySym = nId;
cdf1e714
DW
4649 break;
4650 }
86de7616 4651 }
61243a51
DW
4652 return nKeySym;
4653} // end of wxCharCodeWXToOS2
86de7616 4654
61243a51 4655wxWindow* wxGetActiveWindow()
cdf1e714 4656{
61243a51 4657 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
86de7616 4658
61243a51
DW
4659 if (hWnd != 0)
4660 {
4661 return wxFindWinFromHandle((WXHWND)hWnd);
4662 }
4663 return NULL;
4664} // end of wxGetActiveWindow
cdf1e714
DW
4665
4666#ifdef __WXDEBUG__
4a712ba3 4667const wxChar* wxGetMessageName( int nMessage )
cdf1e714 4668{
61243a51 4669 switch (nMessage)
86de7616 4670 {
4a712ba3
VZ
4671 case 0x0000: return wxT("WM_NULL");
4672 case 0x0001: return wxT("WM_CREATE");
4673 case 0x0002: return wxT("WM_DESTROY");
4674 case 0x0004: return wxT("WM_ENABLE");
4675 case 0x0005: return wxT("WM_SHOW");
4676 case 0x0006: return wxT("WM_MOVE");
4677 case 0x0007: return wxT("WM_SIZE");
4678 case 0x0008: return wxT("WM_ADJUSTWINDOWPOS");
4679 case 0x0009: return wxT("WM_CALCVALIDRECTS");
4680 case 0x000A: return wxT("WM_SETWINDOWPARAMS");
4681 case 0x000B: return wxT("WM_QUERYWINDOWPARAMS");
4682 case 0x000C: return wxT("WM_HITTEST");
4683 case 0x000D: return wxT("WM_ACTIVATE");
4684 case 0x000F: return wxT("WM_SETFOCUS");
4685 case 0x0010: return wxT("WM_SETSELECTION");
4686 case 0x0011: return wxT("WM_PPAINT");
4687 case 0x0012: return wxT("WM_PSETFOCUS");
4688 case 0x0013: return wxT("WM_PSYSCOLORCHANGE");
4689 case 0x0014: return wxT("WM_PSIZE");
4690 case 0x0015: return wxT("WM_PACTIVATE");
4691 case 0x0016: return wxT("WM_PCONTROL");
4692 case 0x0020: return wxT("WM_COMMAND");
4693 case 0x0021: return wxT("WM_SYSCOMMAND");
4694 case 0x0022: return wxT("WM_HELP");
4695 case 0x0023: return wxT("WM_PAINT");
4696 case 0x0024: return wxT("WM_TIMER");
4697 case 0x0025: return wxT("WM_SEM1");
4698 case 0x0026: return wxT("WM_SEM2");
4699 case 0x0027: return wxT("WM_SEM3");
4700 case 0x0028: return wxT("WM_SEM4");
4701 case 0x0029: return wxT("WM_CLOSE");
4702 case 0x002A: return wxT("WM_QUIT");
4703 case 0x002B: return wxT("WM_SYSCOLORCHANGE");
4704 case 0x002D: return wxT("WM_SYSVALUECHANGE");
4705 case 0x002E: return wxT("WM_APPTERMINATENOTIFY");
4706 case 0x002F: return wxT("WM_PRESPARAMCHANGED");
61243a51 4707 // Control notification messages
4a712ba3
VZ
4708 case 0x0030: return wxT("WM_CONTROL");
4709 case 0x0031: return wxT("WM_VSCROLL");
4710 case 0x0032: return wxT("WM_HSCROLL");
4711 case 0x0033: return wxT("WM_INITMENU");
4712 case 0x0034: return wxT("WM_MENUSELECT");
4713 case 0x0035: return wxT("WM_MENUSEND");
4714 case 0x0036: return wxT("WM_DRAWITEM");
4715 case 0x0037: return wxT("WM_MEASUREITEM");
4716 case 0x0038: return wxT("WM_CONTROLPOINTER");
4717 case 0x003A: return wxT("WM_QUERYDLGCODE");
4718 case 0x003B: return wxT("WM_INITDLG");
4719 case 0x003C: return wxT("WM_SUBSTITUTESTRING");
4720 case 0x003D: return wxT("WM_MATCHMNEMONIC");
4721 case 0x003E: return wxT("WM_SAVEAPPLICATION");
4722 case 0x0129: return wxT("WM_CTLCOLORCHANGE");
4723 case 0x0130: return wxT("WM_QUERYCTLTYPE");
61243a51 4724 // Frame messages
4a712ba3
VZ
4725 case 0x0040: return wxT("WM_FLASHWINDOW");
4726 case 0x0041: return wxT("WM_FORMATFRAME");
4727 case 0x0042: return wxT("WM_UPDATEFRAME");
4728 case 0x0043: return wxT("WM_FOCUSCHANGE");
4729 case 0x0044: return wxT("WM_SETBORDERSIZE");
4730 case 0x0045: return wxT("WM_TRACKFRAME");
4731 case 0x0046: return wxT("WM_MINMAXFRAME");
4732 case 0x0047: return wxT("WM_SETICON");
4733 case 0x0048: return wxT("WM_QUERYICON");
4734 case 0x0049: return wxT("WM_SETACCELTABLE");
4735 case 0x004A: return wxT("WM_QUERYACCELTABLE");
4736 case 0x004B: return wxT("WM_TRANSLATEACCEL");
4737 case 0x004C: return wxT("WM_QUERYTRACKINFO");
4738 case 0x004D: return wxT("WM_QUERYBORDERSIZE");
4739 case 0x004E: return wxT("WM_NEXTMENU");
4740 case 0x004F: return wxT("WM_ERASEBACKGROUND");
4741 case 0x0050: return wxT("WM_QUERYFRAMEINFO");
4742 case 0x0051: return wxT("WM_QUERYFOCUSCHAIN");
4743 case 0x0052: return wxT("WM_OWNERPOSCHANGE");
4744 case 0x0053: return wxT("WM_CACLFRAMERECT");
4745 case 0x0055: return wxT("WM_WINDOWPOSCHANGED");
4746 case 0x0056: return wxT("WM_ADJUSTFRAMEPOS");
4747 case 0x0059: return wxT("WM_QUERYFRAMECTLCOUNT");
4748 case 0x005B: return wxT("WM_QUERYHELPINFO");
4749 case 0x005C: return wxT("WM_SETHELPINFO");
4750 case 0x005D: return wxT("WM_ERROR");
4751 case 0x005E: return wxT("WM_REALIZEPALETTE");
61243a51 4752 // Clipboard messages
4a712ba3
VZ
4753 case 0x0060: return wxT("WM_RENDERFMT");
4754 case 0x0061: return wxT("WM_RENDERALLFMTS");
4755 case 0x0062: return wxT("WM_DESTROYCLIPBOARD");
4756 case 0x0063: return wxT("WM_PAINTCLIPBOARD");
4757 case 0x0064: return wxT("WM_SIZECLIPBOARD");
4758 case 0x0065: return wxT("WM_HSCROLLCLIPBOARD");
4759 case 0x0066: return wxT("WM_VSCROLLCLIPBOARD");
4760 case 0x0067: return wxT("WM_DRAWCLIPBOARD");
61243a51 4761 // mouse messages
4a712ba3
VZ
4762 case 0x0070: return wxT("WM_MOUSEMOVE");
4763 case 0x0071: return wxT("WM_BUTTON1DOWN");
4764 case 0x0072: return wxT("WM_BUTTON1UP");
4765 case 0x0073: return wxT("WM_BUTTON1DBLCLK");
4766 case 0x0074: return wxT("WM_BUTTON2DOWN");
4767 case 0x0075: return wxT("WM_BUTTON2UP");
4768 case 0x0076: return wxT("WM_BUTTON2DBLCLK");
4769 case 0x0077: return wxT("WM_BUTTON3DOWN");
4770 case 0x0078: return wxT("WM_BUTTON3UP");
4771 case 0x0079: return wxT("WM_BUTTON3DBLCLK");
4772 case 0x007D: return wxT("WM_MOUSEMAP");
4773 case 0x007E: return wxT("WM_VRNDISABLED");
4774 case 0x007F: return wxT("WM_VRNENABLED");
4775 case 0x0410: return wxT("WM_CHORD");
4776 case 0x0411: return wxT("WM_BUTTON1MOTIONSTART");
4777 case 0x0412: return wxT("WM_BUTTON1MOTIONEND");
4778 case 0x0413: return wxT("WM_BUTTON1CLICK");
4779 case 0x0414: return wxT("WM_BUTTON2MOTIONSTART");
4780 case 0x0415: return wxT("WM_BUTTON2MOTIONEND");
4781 case 0x0416: return wxT("WM_BUTTON2CLICK");
4782 case 0x0417: return wxT("WM_BUTTON3MOTIONSTART");
4783 case 0x0418: return wxT("WM_BUTTON3MOTIONEND");
4784 case 0x0419: return wxT("WM_BUTTON3CLICK");
4785 case 0x0420: return wxT("WM_BEGINDRAG");
4786 case 0x0421: return wxT("WM_ENDDRAG");
4787 case 0x0422: return wxT("WM_SINGLESELECT");
4788 case 0x0423: return wxT("WM_OPEN");
4789 case 0x0424: return wxT("WM_CONTEXTMENU");
4790 case 0x0425: return wxT("WM_CONTEXTHELP");
4791 case 0x0426: return wxT("WM_TEXTEDIT");
4792 case 0x0427: return wxT("WM_BEGINSELECT");
4793 case 0x0228: return wxT("WM_ENDSELECT");
4794 case 0x0429: return wxT("WM_PICKUP");
4795 case 0x04C0: return wxT("WM_PENFIRST");
4796 case 0x04FF: return wxT("WM_PENLAST");
4797 case 0x0500: return wxT("WM_MMPMFIRST");
4798 case 0x05FF: return wxT("WM_MMPMLAST");
4799 case 0x0600: return wxT("WM_STDDLGFIRST");
4800 case 0x06FF: return wxT("WM_STDDLGLAST");
4801 case 0x0BD0: return wxT("WM_BIDI_FIRST");
4802 case 0x0BFF: return wxT("WM_BIDI_LAST");
61243a51 4803 // keyboard input
4a712ba3
VZ
4804 case 0x007A: return wxT("WM_CHAR");
4805 case 0x007B: return wxT("WM_VIOCHAR");
61243a51 4806 // DDE messages
4a712ba3
VZ
4807 case 0x00A0: return wxT("WM_DDE_INITIATE");
4808 case 0x00A1: return wxT("WM_DDE_REQUEST");
4809 case 0x00A2: return wxT("WM_DDE_ACK");
4810 case 0x00A3: return wxT("WM_DDE_DATA");
4811 case 0x00A4: return wxT("WM_DDE_ADVISE");
4812 case 0x00A5: return wxT("WM_DDE_UNADVISE");
4813 case 0x00A6: return wxT("WM_DDE_POKE");
4814 case 0x00A7: return wxT("WM_DDE_EXECUTE");
4815 case 0x00A8: return wxT("WM_DDE_TERMINATE");
4816 case 0x00A9: return wxT("WM_DDE_INITIATEACK");
4817 case 0x00AF: return wxT("WM_DDE_LAST");
61243a51 4818 // Buttons
4a712ba3
VZ
4819 case 0x0120: return wxT("BM_CLICK");
4820 case 0x0121: return wxT("BM_QUERYCHECKINDEX");
4821 case 0x0122: return wxT("BM_QUERYHILITE");
4822 case 0x0123: return wxT("BM_SETHILITE");
4823 case 0x0124: return wxT("BM_QUERYCHECK");
4824 case 0x0125: return wxT("BM_SETCHECK");
4825 case 0x0126: return wxT("BM_SETDEFAULT");
4826 case 0x0128: return wxT("BM_AUTOSIZE");
61243a51 4827 // Combo boxes
4a712ba3
VZ
4828 case 0x029A: return wxT("CBID_LIST");
4829 case 0x029B: return wxT("CBID_EDIT");
4830 case 0x0170: return wxT("CBM_SHOWLIST");
4831 case 0x0171: return wxT("CBM_HILITE");
4832 case 0x0172: return wxT("CBM_ISLISTSHOWING");
61243a51 4833 // Edit fields
4a712ba3
VZ
4834 case 0x0140: return wxT("EM_QUERYCHANGED");
4835 case 0x0141: return wxT("EM_QUERYSEL");
4836 case 0x0142: return wxT("EM_SETSEL");
4837 case 0x0143: return wxT("EM_SETTEXTLIMIT");
4838 case 0x0144: return wxT("EM_CUT");
4839 case 0x0145: return wxT("EM_COPY");
4840 case 0x0146: return wxT("EM_CLEAR");
4841 case 0x0147: return wxT("EM_PASTE");
4842 case 0x0148: return wxT("EM_QUERYFIRSTCHAR");
4843 case 0x0149: return wxT("EM_SETFIRSTCHAR");
4844 case 0x014A: return wxT("EM_QUERYREADONLY");
4845 case 0x014B: return wxT("EM_SETREADONLY");
4846 case 0x014C: return wxT("EM_SETINSERTMODE");
61243a51 4847 // Listboxes
4a712ba3
VZ
4848 case 0x0160: return wxT("LM_QUERYITEMCOUNT");
4849 case 0x0161: return wxT("LM_INSERTITEM");
4850 case 0x0162: return wxT("LM_SETOPENINDEX");
4851 case 0x0163: return wxT("LM_DELETEITEM");
4852 case 0x0164: return wxT("LM_SELECTITEM");
4853 case 0x0165: return wxT("LM_QUERYSELECTION");
4854 case 0x0166: return wxT("LM_SETITEMTEXT");
4855 case 0x0167: return wxT("LM_QUERYITEMTEXTLENGTH");
4856 case 0x0168: return wxT("LM_QUERYITEMTEXT");
4857 case 0x0169: return wxT("LM_SETITEMHANDLE");
4858 case 0x016A: return wxT("LM_QUERYITEMHANDLE");
4859 case 0x016B: return wxT("LM_SEARCHSTRING");
4860 case 0x016C: return wxT("LM_SETITEMHEIGHT");
4861 case 0x016D: return wxT("LM_QUERYTOPINDEX");
4862 case 0x016E: return wxT("LM_DELETEALL");
4863 case 0x016F: return wxT("LM_INSERTMULITEMS");
4864 case 0x0660: return wxT("LM_SETITEMWIDTH");
61243a51 4865 // Menus
4a712ba3
VZ
4866 case 0x0180: return wxT("MM_INSERTITEM");
4867 case 0x0181: return wxT("MM_DELETEITEM");
4868 case 0x0182: return wxT("MM_QUERYITEM");
4869 case 0x0183: return wxT("MM_SETITEM");
4870 case 0x0184: return wxT("MM_QUERYITEMCOUNT");
4871 case 0x0185: return wxT("MM_STARTMENUMODE");
4872 case 0x0186: return wxT("MM_ENDMENUMODE");
4873 case 0x0188: return wxT("MM_REMOVEITEM");
4874 case 0x0189: return wxT("MM_SELECTITEM");
4875 case 0x018A: return wxT("MM_QUERYSELITEMID");
4876 case 0x018B: return wxT("MM_QUERYITEMTEXT");
4877 case 0x018C: return wxT("MM_QUERYITEMTEXTLENGTH");
4878 case 0x018D: return wxT("MM_SETITEMHANDLE");
4879 case 0x018E: return wxT("MM_SETITEMTEXT");
4880 case 0x018F: return wxT("MM_ITEMPOSITIONFROMID");
4881 case 0x0190: return wxT("MM_ITEMIDFROMPOSITION");
4882 case 0x0191: return wxT("MM_QUERYITEMATTR");
4883 case 0x0192: return wxT("MM_SETITEMATTR");
4884 case 0x0193: return wxT("MM_ISITEMVALID");
4885 case 0x0194: return wxT("MM_QUERYITEMRECT");
4886 case 0x0431: return wxT("MM_QUERYDEFAULTITEMID");
4887 case 0x0432: return wxT("MM_SETDEFAULTITEMID");
61243a51 4888 // Scrollbars
4a712ba3
VZ
4889 case 0x01A0: return wxT("SBM_SETSCROLLBAR");
4890 case 0x01A1: return wxT("SBM_SETPOS");
4891 case 0x01A2: return wxT("SBM_QUERYPOS");
4892 case 0x01A3: return wxT("SBM_QUERYRANGE");
4893 case 0x01A6: return wxT("SBM_SETTHUMBSIZE");
61243a51
DW
4894
4895 // Help messages
4a712ba3
VZ
4896 case 0x0F00: return wxT("WM_HELPBASE");
4897 case 0x0FFF: return wxT("WM_HELPTOP");
61243a51 4898 // Beginning of user defined messages
4a712ba3 4899 case 0x1000: return wxT("WM_USER");
61243a51 4900
77ffb593 4901 // wxWidgets user defined types
cdf1e714
DW
4902
4903 // listview
4a712ba3
VZ
4904 // case 0x1000 + 0: return wxT("LVM_GETBKCOLOR");
4905 case 0x1000 + 1: return wxT("LVM_SETBKCOLOR");
4906 case 0x1000 + 2: return wxT("LVM_GETIMAGELIST");
4907 case 0x1000 + 3: return wxT("LVM_SETIMAGELIST");
4908 case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT");
4909 case 0x1000 + 5: return wxT("LVM_GETITEMA");
4910 case 0x1000 + 75: return wxT("LVM_GETITEMW");
4911 case 0x1000 + 6: return wxT("LVM_SETITEMA");
4912 case 0x1000 + 76: return wxT("LVM_SETITEMW");
4913 case 0x1000 + 7: return wxT("LVM_INSERTITEMA");
4914 case 0x1000 + 77: return wxT("LVM_INSERTITEMW");
4915 case 0x1000 + 8: return wxT("LVM_DELETEITEM");
4916 case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS");
4917 case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK");
4918 case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK");
4919 case 0x1000 + 12: return wxT("LVM_GETNEXTITEM");
4920 case 0x1000 + 13: return wxT("LVM_FINDITEMA");
4921 case 0x1000 + 83: return wxT("LVM_FINDITEMW");
4922 case 0x1000 + 14: return wxT("LVM_GETITEMRECT");
4923 case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION");
4924 case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION");
4925 case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA");
4926 case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW");
4927 case 0x1000 + 18: return wxT("LVM_HITTEST");
4928 case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE");
4929 case 0x1000 + 20: return wxT("LVM_SCROLL");
4930 case 0x1000 + 21: return wxT("LVM_REDRAWITEMS");
4931 case 0x1000 + 22: return wxT("LVM_ARRANGE");
4932 case 0x1000 + 23: return wxT("LVM_EDITLABELA");
4933 case 0x1000 + 118: return wxT("LVM_EDITLABELW");
4934 case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL");
4935 case 0x1000 + 25: return wxT("LVM_GETCOLUMNA");
4936 case 0x1000 + 95: return wxT("LVM_GETCOLUMNW");
4937 case 0x1000 + 26: return wxT("LVM_SETCOLUMNA");
4938 case 0x1000 + 96: return wxT("LVM_SETCOLUMNW");
4939 case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA");
4940 case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW");
4941 case 0x1000 + 28: return wxT("LVM_DELETECOLUMN");
4942 case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH");
4943 case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH");
4944 case 0x1000 + 31: return wxT("LVM_GETHEADER");
4945 case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE");
4946 case 0x1000 + 34: return wxT("LVM_GETVIEWRECT");
4947 case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR");
4948 case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR");
4949 case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR");
4950 case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR");
4951 case 0x1000 + 39: return wxT("LVM_GETTOPINDEX");
4952 case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE");
4953 case 0x1000 + 41: return wxT("LVM_GETORIGIN");
4954 case 0x1000 + 42: return wxT("LVM_UPDATE");
4955 case 0x1000 + 43: return wxT("LVM_SETITEMSTATE");
4956 case 0x1000 + 44: return wxT("LVM_GETITEMSTATE");
4957 case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA");
4958 case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW");
4959 case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA");
4960 case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW");
4961 case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT");
4962 case 0x1000 + 48: return wxT("LVM_SORTITEMS");
4963 case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32");
4964 case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT");
4965 case 0x1000 + 51: return wxT("LVM_GETITEMSPACING");
4966 case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA");
4967 case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW");
4968 case 0x1000 + 53: return wxT("LVM_SETICONSPACING");
4969 case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE");
4970 case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE");
4971 case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT");
4972 case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST");
4973 case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY");
4974 case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY");
4975 case 0x1000 + 60: return wxT("LVM_SETHOTITEM");
4976 case 0x1000 + 61: return wxT("LVM_GETHOTITEM");
4977 case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR");
4978 case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR");
4979 case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT");
4980 case 0x1000 + 65: return wxT("LVM_SETWORKAREA");
cdf1e714
DW
4981
4982 // tree view
4a712ba3
VZ
4983 case 0x1100 + 0: return wxT("TVM_INSERTITEMA");
4984 case 0x1100 + 50: return wxT("TVM_INSERTITEMW");
4985 case 0x1100 + 1: return wxT("TVM_DELETEITEM");
4986 case 0x1100 + 2: return wxT("TVM_EXPAND");
4987 case 0x1100 + 4: return wxT("TVM_GETITEMRECT");
4988 case 0x1100 + 5: return wxT("TVM_GETCOUNT");
4989 case 0x1100 + 6: return wxT("TVM_GETINDENT");
4990 case 0x1100 + 7: return wxT("TVM_SETINDENT");
4991 case 0x1100 + 8: return wxT("TVM_GETIMAGELIST");
4992 case 0x1100 + 9: return wxT("TVM_SETIMAGELIST");
4993 case 0x1100 + 10: return wxT("TVM_GETNEXTITEM");
4994 case 0x1100 + 11: return wxT("TVM_SELECTITEM");
4995 case 0x1100 + 12: return wxT("TVM_GETITEMA");
4996 case 0x1100 + 62: return wxT("TVM_GETITEMW");
4997 case 0x1100 + 13: return wxT("TVM_SETITEMA");
4998 case 0x1100 + 63: return wxT("TVM_SETITEMW");
4999 case 0x1100 + 14: return wxT("TVM_EDITLABELA");
5000 case 0x1100 + 65: return wxT("TVM_EDITLABELW");
5001 case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL");
5002 case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT");
5003 case 0x1100 + 17: return wxT("TVM_HITTEST");
5004 case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE");
5005 case 0x1100 + 19: return wxT("TVM_SORTCHILDREN");
5006 case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE");
5007 case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB");
5008 case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW");
5009 case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA");
5010 case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW");
5011 case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS");
5012 case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS");
cdf1e714
DW
5013
5014 // header
4a712ba3
VZ
5015 case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT");
5016 case 0x1200 + 1: return wxT("HDM_INSERTITEMA");
5017 case 0x1200 + 10: return wxT("HDM_INSERTITEMW");
5018 case 0x1200 + 2: return wxT("HDM_DELETEITEM");
5019 case 0x1200 + 3: return wxT("HDM_GETITEMA");
5020 case 0x1200 + 11: return wxT("HDM_GETITEMW");
5021 case 0x1200 + 4: return wxT("HDM_SETITEMA");
5022 case 0x1200 + 12: return wxT("HDM_SETITEMW");
5023 case 0x1200 + 5: return wxT("HDM_LAYOUT");
5024 case 0x1200 + 6: return wxT("HDM_HITTEST");
5025 case 0x1200 + 7: return wxT("HDM_GETITEMRECT");
5026 case 0x1200 + 8: return wxT("HDM_SETIMAGELIST");
5027 case 0x1200 + 9: return wxT("HDM_GETIMAGELIST");
5028 case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX");
5029 case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE");
5030 case 0x1200 + 17: return wxT("HDM_GETORDERARRAY");
5031 case 0x1200 + 18: return wxT("HDM_SETORDERARRAY");
5032 case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER");
cdf1e714
DW
5033
5034 // tab control
4a712ba3
VZ
5035 case 0x1300 + 2: return wxT("TCM_GETIMAGELIST");
5036 case 0x1300 + 3: return wxT("TCM_SETIMAGELIST");
5037 case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT");
5038 case 0x1300 + 5: return wxT("TCM_GETITEMA");
5039 case 0x1300 + 60: return wxT("TCM_GETITEMW");
5040 case 0x1300 + 6: return wxT("TCM_SETITEMA");
5041 case 0x1300 + 61: return wxT("TCM_SETITEMW");
5042 case 0x1300 + 7: return wxT("TCM_INSERTITEMA");
5043 case 0x1300 + 62: return wxT("TCM_INSERTITEMW");
5044 case 0x1300 + 8: return wxT("TCM_DELETEITEM");
5045 case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS");
5046 case 0x1300 + 10: return wxT("TCM_GETITEMRECT");
5047 case 0x1300 + 11: return wxT("TCM_GETCURSEL");
5048 case 0x1300 + 12: return wxT("TCM_SETCURSEL");
5049 case 0x1300 + 13: return wxT("TCM_HITTEST");
5050 case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA");
5051 case 0x1300 + 40: return wxT("TCM_ADJUSTRECT");
5052 case 0x1300 + 41: return wxT("TCM_SETITEMSIZE");
5053 case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE");
5054 case 0x1300 + 43: return wxT("TCM_SETPADDING");
5055 case 0x1300 + 44: return wxT("TCM_GETROWCOUNT");
5056 case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS");
5057 case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS");
5058 case 0x1300 + 47: return wxT("TCM_GETCURFOCUS");
5059 case 0x1300 + 48: return wxT("TCM_SETCURFOCUS");
5060 case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH");
5061 case 0x1300 + 50: return wxT("TCM_DESELECTALL");
cdf1e714
DW
5062
5063 // toolbar
4a712ba3
VZ
5064 case WM_USER+1000+1: return wxT("TB_ENABLEBUTTON");
5065 case WM_USER+1000+2: return wxT("TB_CHECKBUTTON");
5066 case WM_USER+1000+3: return wxT("TB_PRESSBUTTON");
5067 case WM_USER+1000+4: return wxT("TB_HIDEBUTTON");
5068 case WM_USER+1000+5: return wxT("TB_INDETERMINATE");
5069 case WM_USER+1000+9: return wxT("TB_ISBUTTONENABLED");
5070 case WM_USER+1000+10: return wxT("TB_ISBUTTONCHECKED");
5071 case WM_USER+1000+11: return wxT("TB_ISBUTTONPRESSED");
5072 case WM_USER+1000+12: return wxT("TB_ISBUTTONHIDDEN");
5073 case WM_USER+1000+13: return wxT("TB_ISBUTTONINDETERMINATE");
5074 case WM_USER+1000+17: return wxT("TB_SETSTATE");
5075 case WM_USER+1000+18: return wxT("TB_GETSTATE");
5076 case WM_USER+1000+19: return wxT("TB_ADDBITMAP");
5077 case WM_USER+1000+20: return wxT("TB_ADDBUTTONS");
5078 case WM_USER+1000+21: return wxT("TB_INSERTBUTTON");
5079 case WM_USER+1000+22: return wxT("TB_DELETEBUTTON");
5080 case WM_USER+1000+23: return wxT("TB_GETBUTTON");
5081 case WM_USER+1000+24: return wxT("TB_BUTTONCOUNT");
5082 case WM_USER+1000+25: return wxT("TB_COMMANDTOINDEX");
5083 case WM_USER+1000+26: return wxT("TB_SAVERESTOREA");
5084 case WM_USER+1000+76: return wxT("TB_SAVERESTOREW");
5085 case WM_USER+1000+27: return wxT("TB_CUSTOMIZE");
5086 case WM_USER+1000+28: return wxT("TB_ADDSTRINGA");
5087 case WM_USER+1000+77: return wxT("TB_ADDSTRINGW");
5088 case WM_USER+1000+29: return wxT("TB_GETITEMRECT");
5089 case WM_USER+1000+30: return wxT("TB_BUTTONSTRUCTSIZE");
5090 case WM_USER+1000+31: return wxT("TB_SETBUTTONSIZE");
5091 case WM_USER+1000+32: return wxT("TB_SETBITMAPSIZE");
5092 case WM_USER+1000+33: return wxT("TB_AUTOSIZE");
5093 case WM_USER+1000+35: return wxT("TB_GETTOOLTIPS");
5094 case WM_USER+1000+36: return wxT("TB_SETTOOLTIPS");
5095 case WM_USER+1000+37: return wxT("TB_SETPARENT");
5096 case WM_USER+1000+39: return wxT("TB_SETROWS");
5097 case WM_USER+1000+40: return wxT("TB_GETROWS");
5098 case WM_USER+1000+42: return wxT("TB_SETCMDID");
5099 case WM_USER+1000+43: return wxT("TB_CHANGEBITMAP");
5100 case WM_USER+1000+44: return wxT("TB_GETBITMAP");
5101 case WM_USER+1000+45: return wxT("TB_GETBUTTONTEXTA");
5102 case WM_USER+1000+75: return wxT("TB_GETBUTTONTEXTW");
5103 case WM_USER+1000+46: return wxT("TB_REPLACEBITMAP");
5104 case WM_USER+1000+47: return wxT("TB_SETINDENT");
5105 case WM_USER+1000+48: return wxT("TB_SETIMAGELIST");
5106 case WM_USER+1000+49: return wxT("TB_GETIMAGELIST");
5107 case WM_USER+1000+50: return wxT("TB_LOADIMAGES");
5108 case WM_USER+1000+51: return wxT("TB_GETRECT");
5109 case WM_USER+1000+52: return wxT("TB_SETHOTIMAGELIST");
5110 case WM_USER+1000+53: return wxT("TB_GETHOTIMAGELIST");
5111 case WM_USER+1000+54: return wxT("TB_SETDISABLEDIMAGELIST");
5112 case WM_USER+1000+55: return wxT("TB_GETDISABLEDIMAGELIST");
5113 case WM_USER+1000+56: return wxT("TB_SETSTYLE");
5114 case WM_USER+1000+57: return wxT("TB_GETSTYLE");
5115 case WM_USER+1000+58: return wxT("TB_GETBUTTONSIZE");
5116 case WM_USER+1000+59: return wxT("TB_SETBUTTONWIDTH");
5117 case WM_USER+1000+60: return wxT("TB_SETMAXTEXTROWS");
5118 case WM_USER+1000+61: return wxT("TB_GETTEXTROWS");
5119 case WM_USER+1000+41: return wxT("TB_GETBITMAPFLAGS");
86de7616 5120 }
6670f564 5121
4a712ba3 5122 static wxString s_szBuf;
ebeb1b6a 5123 s_szBuf.Printf(wxT("<unknown message = %d>"), nMessage);
4a712ba3 5124 return s_szBuf.c_str();
6670f564 5125
61243a51 5126} // end of wxGetMessageName
86de7616 5127
11e59d47
DW
5128#endif // __WXDEBUG__
5129
19193a2c
KB
5130// Unused?
5131#if 0
61243a51
DW
5132static void TranslateKbdEventToMouse(
5133 wxWindow* pWin
5134, int* pX
5135, int* pY
5136, ULONG* pFlags
5137)
5138{
5139 //
5140 // Construct the key mask
5141 ULONG& fwKeys = *pFlags;
5142
5143 fwKeys = VK_BUTTON2;
5144 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
5145 fwKeys |= VK_CTRL;
5146 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
5147 fwKeys |= VK_SHIFT;
5148
5149 //
5150 // Simulate right mouse button click
5151 //
5152 POINTL vPoint;
5153
5154 ::WinQueryMsgPos(vHabmain, &vPoint);
5155 *pX = vPoint.x;
5156 *pY = vPoint.y;
5157
5158 pWin->ScreenToClient(pX, pY);
5159} // end of TranslateKbdEventToMouse
19193a2c 5160#endif
61243a51 5161
cd212ee4
DW
5162// Find the wxWindow at the current mouse position, returning the mouse
5163// position.
1a4138c7 5164wxWindow* wxFindWindowAtPointer(wxPoint& WXUNUSED(rPt))
cd212ee4
DW
5165{
5166 return wxFindWindowAtPoint(wxGetMousePosition());
5167}
5168
1a4138c7 5169wxWindow* wxFindWindowAtPoint(const wxPoint& rPt)
cd212ee4 5170{
f44fdfb0 5171 POINTL vPt2;
cd212ee4 5172
f44fdfb0
DW
5173 vPt2.x = rPt.x;
5174 vPt2.y = rPt.y;
cd212ee4 5175
f44fdfb0
DW
5176 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
5177 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
5178 HWND hWnd = hWndHit;
5179
5180 //
cd212ee4 5181 // Try to find a window with a wxWindow associated with it
f44fdfb0
DW
5182 //
5183 while (!pWin && (hWnd != 0))
cd212ee4 5184 {
f44fdfb0
DW
5185 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
5186 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
cd212ee4 5187 }
f44fdfb0 5188 return pWin;
cd212ee4
DW
5189}
5190
f44fdfb0
DW
5191// Get the current mouse position.
5192wxPoint wxGetMousePosition()
5193{
5194 POINTL vPt;
5195
5196 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
5197 return wxPoint(vPt.x, vPt.y);
5198}
cd212ee4 5199
6670f564
WS
5200wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin,
5201 short* WXUNUSED(pnX),
5202 short* WXUNUSED(pnY) )
430974f8 5203{
77f4f0a7
WS
5204 HWND hWnd = GetHwndOf(pWin);
5205 HWND hWndUnderMouse;
5206 POINTL vPoint;
5207 BOOL rcEnabled = FALSE;
5208 BOOL rcVisible = FALSE;
430974f8 5209
b720b24d
DW
5210 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
5211 hWndUnderMouse = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
5212 if (hWndUnderMouse != HWND_DESKTOP)
430974f8 5213 {
b720b24d
DW
5214 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5215
5216 if (pWinUnderMouse)
5217 {
2461cfa0 5218 wxWindowList::compatibility_iterator current = pWinUnderMouse->GetChildren().GetFirst();
b720b24d
DW
5219 wxWindow* pGrandChild = NULL;
5220 RECTL vRect;
5221 POINTL vPoint2;
5222
5223 ::WinMapWindowPoints(HWND_DESKTOP, hWndUnderMouse, &vPoint, 1);
5224 //
5225 // Find a child window mouse might be under
5226 //
2461cfa0 5227 while (current)
b720b24d 5228 {
2461cfa0 5229 wxWindow* pChild = current->GetData();
b720b24d
DW
5230
5231 vPoint2.x = vPoint.x;
5232 vPoint2.y = vPoint.y;
5233 ::WinMapWindowPoints(hWndUnderMouse, pChild->GetHWND(), &vPoint2, 1);
5234 ::WinQueryWindowRect(pChild->GetHWND(), &vRect);
5235 if (::WinPtInRect(vHabmain, &vRect, &vPoint2))
5236 {
5237 if (pChild->IsTopLevel())
5238 {
5239 POINTL vPoint3;
2461cfa0 5240 wxWindowList::compatibility_iterator current2 =pChild->GetChildren().GetFirst();
430974f8 5241
2461cfa0 5242 while (current2)
b720b24d 5243 {
2461cfa0 5244 wxWindow* pGrandChild = current2->GetData();
b720b24d
DW
5245
5246 vPoint3.x = vPoint2.x;
5247 vPoint3.y = vPoint2.y;
5248 ::WinMapWindowPoints( pChild->GetHWND()
5249 ,pGrandChild->GetHWND()
5250 ,&vPoint3
5251 ,1
5252 );
5253 ::WinQueryWindowRect(pGrandChild->GetHWND(), &vRect);
5254 if (::WinPtInRect(vHabmain, &vRect, &vPoint3))
5255 {
5256 hWndUnderMouse = GetHwndOf(pGrandChild);
5257 pWinUnderMouse = pGrandChild;
5258 break;
5259 }
2461cfa0 5260 current2 = current2->GetNext();
b720b24d
DW
5261 }
5262 if (pGrandChild)
5263 break;
5264 }
5265 hWndUnderMouse = GetHwndOf(pChild);
5266 pWinUnderMouse = pChild;
5267 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5268 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5269 if (rcVisible && rcEnabled)
5270 break;
5271 }
2461cfa0 5272 current = current->GetNext();
b720b24d
DW
5273 }
5274 }
430974f8 5275 }
b720b24d
DW
5276 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5277 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5278
430974f8
DW
5279
5280 //
5281 // Check that we have a child window which is susceptible to receive mouse
5282 // events: for this it must be shown and enabled
b720b24d 5283 //
430974f8
DW
5284 if ( hWndUnderMouse &&
5285 hWndUnderMouse != hWnd &&
b720b24d 5286 rcVisible && rcEnabled)
430974f8 5287 {
b720b24d
DW
5288 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5289
430974f8
DW
5290 if (pWinUnderMouse)
5291 {
b720b24d
DW
5292 //
5293 // Translate the mouse coords to the other window coords
5294 //
430974f8
DW
5295 pWin = pWinUnderMouse;
5296 }
5297 }
5298 return pWin;
5299} // end of FindWindowForMouseEvent