]> git.saurik.com Git - wxWidgets.git/blame - src/os2/window.cpp
1. restored wxEvent::operator=()
[wxWidgets.git] / src / os2 / window.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
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
DW
8// Copyright: (c) David Webster
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"
31 #include "wx/dialog.h"
32 #include "wx/frame.h"
33 #include "wx/listbox.h"
34 #include "wx/button.h"
35 #include "wx/msgdlg.h"
19193a2c 36 #include "wx/scrolwin.h"
849949b1
DW
37
38 #include <stdio.h>
39#endif
40
41#if wxUSE_OWNER_DRAWN
42 #include "wx/ownerdrw.h"
43#endif
44
45#if wxUSE_DRAG_AND_DROP
46 #include "wx/dnd.h"
47#endif
0e320a79
DW
48
49#include "wx/menuitem.h"
50#include "wx/log.h"
51
cdf1e714
DW
52#include "wx/os2/private.h"
53
849949b1
DW
54#if wxUSE_TOOLTIPS
55 #include "wx/tooltip.h"
0e320a79
DW
56#endif
57
849949b1
DW
58#if wxUSE_CARET
59 #include "wx/caret.h"
60#endif // wxUSE_CARET
61
62#include "wx/intl.h"
63#include "wx/log.h"
64
65
66#include "wx/textctrl.h"
67
0e320a79
DW
68#include <string.h>
69
a885d89a
DW
70//
71// Place compiler, OS specific includes here
72//
849949b1 73
a885d89a
DW
74//
75// Standard macros -- these are for OS/2 PM, but most GUI's have something similar
76//
849949b1 77#ifndef GET_X_LPARAM
a885d89a 78//
849949b1 79// SHORT1FROMMP -- LOWORD
a885d89a 80//
849949b1 81 #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp))
a885d89a 82//
849949b1 83// SHORT2FROMMP -- HIWORD
a885d89a 84//
849949b1
DW
85 #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16))
86#endif // GET_X_LPARAM
87
29a99be3
DW
88#ifndef CW_USEDEFAULT
89# define CW_USEDEFAULT ((int)0x80000000)
90#endif
91
849949b1
DW
92// ---------------------------------------------------------------------------
93// global variables
94// ---------------------------------------------------------------------------
95
a885d89a 96//
19193a2c 97// The last PM message we got (MT-UNSAFE)
a885d89a 98//
61243a51 99QMSG s_currentMsg;
849949b1 100
19193a2c 101#if wxUSE_MENUS_NATIVE
a885d89a 102wxMenu* wxCurrentPopupMenu = NULL;
19193a2c
KB
103#endif // wxUSE_MENUS_NATIVE
104
8138a3b0
SN
105#if !defined(__VISAGECPP__) || (__IBMCPP__ < 400)
106extern wxChar wxCanvasClassName[];
61243a51 107#endif
a885d89a 108wxList* wxWinHandleList = NULL;
849949b1
DW
109
110// ---------------------------------------------------------------------------
111// private functions
112// ---------------------------------------------------------------------------
a885d89a
DW
113
114//
849949b1 115// the window proc for all our windows; most gui's have something similar
a885d89a 116//
f23208ca
DW
117MRESULT EXPENTRY wxWndProc( HWND hWnd
118 ,ULONG message
119 ,MPARAM mp1
120 ,MPARAM mp2
121 );
11e59d47
DW
122
123#ifdef __WXDEBUG__
124 const char *wxGetMessageName(int message);
125#endif //__WXDEBUG__
126
19193a2c
KB
127void wxRemoveHandleAssociation(wxWindowOS2* pWin);
128void wxAssociateWinWithHandle( HWND hWnd
129 ,wxWindowOS2* pWin
a885d89a
DW
130 );
131wxWindow* wxFindWinFromHandle(WXHWND hWnd);
849949b1 132
a885d89a
DW
133//
134// This magical function is used to translate VK_APPS key presses to right
135// mouse clicks
136//
19193a2c
KB
137// Unused?
138#if 0
a885d89a
DW
139static void TranslateKbdEventToMouse( wxWindow* pWin
140 ,int* pX
141 ,int* pY
142 ,MPARAM* pFlags
143 );
19193a2c 144#endif
a885d89a
DW
145//
146// get the current state of SHIFT/CTRL keys
147//
148static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
149static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
849949b1
DW
150// ---------------------------------------------------------------------------
151// event tables
152// ---------------------------------------------------------------------------
0e320a79 153
19193a2c
KB
154// in wxUniv-OS/2 this class is abstract because it doesn't have DoPopupMenu()
155// method
156#ifdef __WXUNIVERSAL__
157 IMPLEMENT_ABSTRACT_CLASS(wxWindowOS2, wxWindowBase)
158#else // __WXPM__
849949b1 159 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
19193a2c 160#endif // __WXUNIVERSAL__/__WXPM__
0e320a79 161
19193a2c 162BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
0367c1c0
DW
163 EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
164 EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
165 EVT_INIT_DIALOG(wxWindowOS2::OnInitDialog)
166 EVT_IDLE(wxWindowOS2::OnIdle)
167 EVT_SET_FOCUS(wxWindowOS2::OnSetFocus)
849949b1 168END_EVENT_TABLE()
0e320a79 169
849949b1
DW
170// ===========================================================================
171// implementation
172// ===========================================================================
0e320a79 173
19193a2c
KB
174// ---------------------------------------------------------------------------
175// wxWindow utility functions
176// ---------------------------------------------------------------------------
177
a885d89a 178//
776d87d5 179// Find an item given the PM Window id
a885d89a 180//
0367c1c0 181wxWindow* wxWindowOS2::FindItem(
a885d89a 182 long lId
776d87d5 183) const
cdf1e714 184{
19193a2c
KB
185#if wxUSE_CONTROLS
186 wxControl* pItem = wxDynamicCast(this, wxControl);
a885d89a
DW
187
188 if (pItem)
189 {
190 //
191 // I it we or one of our "internal" children?
192 //
19193a2c
KB
193 if (pItem->GetId() == lId
194#ifndef __WXUNIVERSAL__
195 || (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)
196#endif
197 )
a885d89a
DW
198 {
199 return pItem;
200 }
201 }
19193a2c 202#endif // wxUSE_CONTROLS
a885d89a 203
776d87d5
DW
204 wxWindowList::Node* pCurrent = GetChildren().GetFirst();
205
206 while (pCurrent)
cdf1e714 207 {
776d87d5 208 wxWindow* pChildWin = pCurrent->GetData();
a885d89a 209 wxWindow* pWnd = pChildWin->FindItem(lId);
cdf1e714 210
776d87d5
DW
211 if (pWnd)
212 return pWnd;
cdf1e714 213
776d87d5 214 pCurrent = pCurrent->GetNext();
cdf1e714 215 }
776d87d5 216 return(NULL);
0367c1c0 217} // end of wxWindowOS2::FindItem
cdf1e714 218
a885d89a 219//
776d87d5 220// Find an item given the PM Window handle
a885d89a 221//
0367c1c0 222wxWindow* wxWindowOS2::FindItemByHWND(
776d87d5
DW
223 WXHWND hWnd
224, bool bControlOnly
225) const
cdf1e714 226{
776d87d5
DW
227 wxWindowList::Node* pCurrent = GetChildren().GetFirst();
228
229 while (pCurrent)
cdf1e714 230 {
776d87d5 231 wxWindow* pParent = pCurrent->GetData();
cdf1e714 232
a885d89a 233 //
cdf1e714 234 // Do a recursive search.
a885d89a 235 //
776d87d5
DW
236 wxWindow* pWnd = pParent->FindItemByHWND(hWnd);
237
238 if (pWnd)
239 return(pWnd);
cdf1e714 240
19193a2c
KB
241 if (!bControlOnly
242#if wxUSE_CONTROLS
243 || pParent->IsKindOf(CLASSINFO(wxControl))
244#endif // wxUSE_CONTROLS
245 )
cdf1e714 246 {
776d87d5
DW
247 wxWindow* pItem = pCurrent->GetData();
248
249 if (pItem->GetHWND() == hWnd)
250 return(pItem);
cdf1e714
DW
251 else
252 {
776d87d5
DW
253 if (pItem->ContainsHWND(hWnd))
254 return(pItem);
cdf1e714
DW
255 }
256 }
776d87d5 257 pCurrent = pCurrent->GetNext();
cdf1e714 258 }
776d87d5 259 return(NULL);
0367c1c0 260} // end of wxWindowOS2::FindItemByHWND
cdf1e714 261
a885d89a 262//
cdf1e714 263// Default command handler
a885d89a 264//
0367c1c0 265bool wxWindowOS2::OS2Command(
776d87d5
DW
266 WXUINT WXUNUSED(uParam)
267, WXWORD WXUNUSED(uId)
268)
cdf1e714 269{
776d87d5 270 return(FALSE);
cdf1e714
DW
271}
272
273// ----------------------------------------------------------------------------
274// constructors and such
275// ----------------------------------------------------------------------------
276
0367c1c0 277void wxWindowOS2::Init()
0e320a79 278{
a885d89a
DW
279 //
280 // Generic
281 //
849949b1 282 InitBase();
0e320a79 283
a885d89a 284 //
849949b1 285 // PM specific
a885d89a 286 //
776d87d5
DW
287 m_bDoubleClickAllowed = 0;
288 m_bWinCaptured = FALSE;
cdf1e714 289
849949b1 290 m_isBeingDeleted = FALSE;
776d87d5
DW
291 m_fnOldWndProc = 0;
292 m_bUseCtl3D = FALSE;
293 m_bMouseInWindow = FALSE;
0e320a79 294
a885d89a 295 //
849949b1 296 // wxWnd
a885d89a 297 //
c8b5f745
DW
298 m_hMenu = 0L;
299 m_hWnd = 0L;
300 m_hWndScrollBarHorz = 0L;
301 m_hWndScrollBarVert = 0L;
0e320a79 302
a885d89a
DW
303 //
304 // Pass WM_GETDLGCODE to DefWindowProc()
849949b1 305 m_lDlgCode = 0;
0e320a79 306
776d87d5
DW
307 m_nXThumbSize = 0;
308 m_nYThumbSize = 0;
309 m_bBackgroundTransparent = FALSE;
0e320a79 310
a885d89a
DW
311 //
312 // As all windows are created with WS_VISIBLE style...
313 //
849949b1 314 m_isShown = TRUE;
0e320a79 315
cdf1e714 316#if wxUSE_MOUSEEVENT_HACK
776d87d5
DW
317 m_lLastMouseX =
318 m_lLastMouseY = -1;
319 m_nLastMouseEvent = -1;
cdf1e714 320#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 321} // wxWindowOS2::Init
0e320a79 322
a885d89a 323//
849949b1 324// Destructor
a885d89a 325//
0367c1c0 326wxWindowOS2::~wxWindowOS2()
0e320a79 327{
849949b1 328 m_isBeingDeleted = TRUE;
0e320a79 329
cdf1e714 330 OS2DetachWindowMenu();
1ec46a5b
DW
331 for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
332 {
333 wxFrame* pFrame = wxDynamicCast(pWin, wxFrame);
334
335 if (pFrame)
336 {
337 if (pFrame->GetLastFocus() == this)
338 pFrame->SetLastFocus((wxWindow*)NULL);
1ec46a5b
DW
339 }
340 }
19193a2c
KB
341
342 DestroyChildren();
343
849949b1
DW
344 if (m_parent)
345 m_parent->RemoveChild(this);
e604d44b 346
849949b1
DW
347 if (m_hWnd)
348 {
a885d89a 349 if(!::WinDestroyWindow(GetHWND()))
223d09f6 350 wxLogLastError(wxT("DestroyWindow"));
a885d89a 351 //
849949b1 352 // remove hWnd <-> wxWindow association
a885d89a 353 //
849949b1
DW
354 wxRemoveHandleAssociation(this);
355 }
0367c1c0 356} // end of wxWindowOS2::~wxWindowOS2
0e320a79 357
19193a2c 358// real construction (Init() must have been called before!)
0367c1c0 359bool wxWindowOS2::Create(
776d87d5
DW
360 wxWindow* pParent
361, wxWindowID vId
362, const wxPoint& rPos
363, const wxSize& rSize
364, long lStyle
365, const wxString& rName
366)
367{
f23208ca 368 HWND hParent = NULLHANDLE;
45bfc84b 369 wxPoint vPos = rPos; // The OS/2 position
19193a2c
KB
370 ULONG ulCreateFlags = 0;
371 WXDWORD dwExStyle = 0;
f23208ca 372
776d87d5
DW
373 wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent"));
374
375 if ( !CreateBase( pParent
376 ,vId
377 ,rPos
378 ,rSize
379 ,lStyle
380 ,wxDefaultValidator
381 ,rName
382 ))
383 return(FALSE);
384
f23208ca
DW
385 if (pParent)
386 {
b7d8f285
DW
387 int nTempy;
388
f23208ca
DW
389 pParent->AddChild(this);
390 hParent = GetWinHwnd(pParent);
cb71578c 391
cb71578c
DW
392 if ( pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
393 pParent->IsKindOf(CLASSINFO(wxScrolledWindow))
394 )
395 ulCreateFlags |= WS_CLIPSIBLINGS;
f23208ca 396 }
776d87d5 397
a885d89a 398 //
f23208ca
DW
399 // Most wxSTYLES are really PM Class specific styles and will be
400 // set in those class create procs. PM's basic windows styles are
401 // very limited.
a885d89a 402 //
51c1d535
DW
403 ulCreateFlags |= WS_VISIBLE;
404
405
19193a2c
KB
406#ifdef __WXUNIVERSAL__
407 // no 3d effects, we draw them ourselves
408 WXDWORD exStyle = 0;
409#else // !wxUniversal
cb71578c 410 if (lStyle & wxCLIP_SIBLINGS)
51c1d535
DW
411 ulCreateFlags |= WS_CLIPSIBLINGS;
412
a885d89a 413 if (lStyle & wxCLIP_CHILDREN )
f23208ca 414 ulCreateFlags |= WS_CLIPCHILDREN;
a885d89a 415
f23208ca 416 //
008089f6 417 //
f23208ca 418 //
776d87d5 419 bool bWant3D;
19193a2c
KB
420 dwExStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &bWant3D);
421
422#endif
008089f6
DW
423
424 //
425 // Add the simple border style as we'll use this to draw borders
426 //
427 if (lStyle & wxSIMPLE_BORDER)
428 dwExStyle |= wxSIMPLE_BORDER;
776d87d5 429
19193a2c
KB
430 if (lStyle & wxPOPUP_WINDOW)
431 {
432 // a popup window floats on top of everything
433//TODO: fix this...
434// exStyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
435
436 // it is also created hidden as other top level windows
437 ulCreateFlags &= ~WS_VISIBLE;
438 m_isShown = FALSE;
439 }
440
a885d89a 441 //
f23208ca
DW
442 // Generic OS/2 Windows are created with no owner, no Z Order, no Control data,
443 // and no presentation parameters
a885d89a 444 //
f23208ca
DW
445 OS2Create( hParent
446 ,(PSZ)wxCanvasClassName
447 ,rName.c_str()
448 ,ulCreateFlags
45bfc84b
DW
449 ,vPos.x
450 ,vPos.y
776d87d5
DW
451 ,WidthDefault(rSize.x)
452 ,HeightDefault(rSize.y)
f23208ca
DW
453 ,NULLHANDLE
454 ,NULLHANDLE
455 ,m_windowId
008089f6
DW
456 ,NULL
457 ,NULL
458 ,dwExStyle
776d87d5 459 );
e604d44b 460
776d87d5 461 return(TRUE);
0367c1c0 462} // end of wxWindowOS2::Create
0e320a79 463
cdf1e714
DW
464// ---------------------------------------------------------------------------
465// basic operations
466// ---------------------------------------------------------------------------
0e320a79 467
0367c1c0 468void wxWindowOS2::SetFocus()
0e320a79 469{
bbdc9a87 470 HWND hWnd = GetHwnd();
19193a2c 471 wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
bbdc9a87
DW
472
473 if (hWnd)
474 ::WinSetFocus(HWND_DESKTOP, hWnd);
0367c1c0 475} // end of wxWindowOS2::SetFocus
0e320a79 476
11e59d47 477wxWindow* wxWindowBase::FindFocus()
0e320a79 478{
bbdc9a87
DW
479 HWND hWnd = ::WinQueryFocus(HWND_DESKTOP);
480
481 if (hWnd)
482 {
483 return wxFindWinFromHandle((WXHWND)hWnd);
484 }
485 return NULL;
a885d89a 486} // wxWindowBase::FindFocus
0e320a79 487
0367c1c0 488bool wxWindowOS2::Enable(
bbdc9a87
DW
489 bool bEnable
490)
0e320a79 491{
bbdc9a87
DW
492 if (!wxWindowBase::Enable(bEnable))
493 return(FALSE);
494
495 HWND hWnd = GetHwnd();
496
497 if ( hWnd )
498 ::WinEnableWindow(hWnd, (BOOL)bEnable);
499
500 wxWindowList::Node* pNode = GetChildren().GetFirst();
501
502 while (pNode)
503 {
504 wxWindow* pChild = pNode->GetData();
505
506 pChild->Enable(bEnable);
507 pNode = pNode->GetNext();
508 }
19193a2c 509 return TRUE;
0367c1c0 510} // end of wxWindowOS2::Enable
0e320a79 511
0367c1c0 512bool wxWindowOS2::Show(
bbdc9a87
DW
513 bool bShow
514)
0e320a79 515{
bbdc9a87
DW
516 if (!wxWindowBase::Show(bShow))
517 return(FALSE);
518
519 HWND hWnd = GetHwnd();
520
521 ::WinShowWindow(hWnd, bShow);
522
523 if (bShow)
524 {
a885d89a 525 ::WinSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
bbdc9a87 526 }
19193a2c 527 return TRUE;
0367c1c0 528} // end of wxWindowOS2::Show
0e320a79 529
0367c1c0 530void wxWindowOS2::Raise()
0e320a79 531{
a885d89a 532 ::WinSetWindowPos(GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_ACTIVATE);
0367c1c0 533} // end of wxWindowOS2::Raise
0e320a79 534
0367c1c0 535void wxWindowOS2::Lower()
0e320a79 536{
a885d89a 537 ::WinSetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE);
0367c1c0 538} // end of wxWindowOS2::Lower
0e320a79 539
0367c1c0 540void wxWindowOS2::SetTitle(
bbdc9a87
DW
541 const wxString& rTitle
542)
0e320a79 543{
f38374d0 544 ::WinSetWindowText(GetHwnd(), rTitle.c_str());
0367c1c0 545} // end of wxWindowOS2::SetTitle
0e320a79 546
0367c1c0 547wxString wxWindowOS2::GetTitle() const
0e320a79 548{
cdf1e714 549 return wxGetWindowText(GetHWND());
0367c1c0 550} // end of wxWindowOS2::GetTitle
0e320a79 551
0367c1c0 552void wxWindowOS2::CaptureMouse()
0e320a79 553{
f38374d0
DW
554 HWND hWnd = GetHwnd();
555
556 if (hWnd && !m_bWinCaptured)
557 {
558 ::WinSetCapture(HWND_DESKTOP, hWnd);
559 m_bWinCaptured = TRUE;
560 }
0367c1c0 561} // end of wxWindowOS2::GetTitle
0e320a79 562
0367c1c0 563void wxWindowOS2::ReleaseMouse()
0e320a79 564{
a885d89a 565 if (m_bWinCaptured)
f38374d0
DW
566 {
567 ::WinSetCapture(HWND_DESKTOP, NULLHANDLE);
568 m_bWinCaptured = FALSE;
569 }
0367c1c0 570} // end of wxWindowOS2::ReleaseMouse
0e320a79 571
0367c1c0
DW
572/* static */ wxWindow* wxWindowBase::GetCapture()
573{
574 HWND hwnd = ::WinQueryCapture(HWND_DESKTOP);
575 return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
576} // end of wxWindowBase::GetCapture
577
578bool wxWindowOS2::SetFont(
f38374d0
DW
579 const wxFont& rFont
580)
0e320a79 581{
f38374d0
DW
582 if (!wxWindowBase::SetFont(rFont))
583 {
584 // nothing to do
585 return(FALSE);
586 }
587
588 HWND hWnd = GetHwnd();
589
590 if (hWnd != 0)
591 {
987da0d4
DW
592 char zFont[128];
593 char zFacename[30];
594 char zWeight[30];
595 char zStyle[30];
596
597 //
598 // The fonts available for Presentation Params are just three
599 // outline fonts, the rest are available to the GPI, so we must
600 // map the families to one of these three
601 //
602 switch(rFont.GetFamily())
603 {
604 case wxSCRIPT:
605 case wxDECORATIVE:
606 case wxROMAN:
607 strcpy(zFacename,"Times New Roman");
608 break;
f38374d0 609
987da0d4
DW
610 case wxTELETYPE:
611 case wxMODERN:
612 strcpy(zFacename, "Courier");
613 break;
614
615 case wxSWISS:
616 case wxDEFAULT:
617 default:
618 strcpy(zFacename, "Helvetica");
619 break;
620 }
621
622 switch(rFont.GetWeight())
623 {
624 default:
625 case wxNORMAL:
626 case wxLIGHT:
627 zWeight[0] = '\0';
628 break;
629
630 case wxBOLD:
631 case wxFONTWEIGHT_MAX:
632 strcpy(zWeight, "Bold");
633 break;
634 }
635 switch(rFont.GetStyle())
636 {
637 case wxITALIC:
638 case wxSLANT:
639 strcpy(zStyle, "Italic");
640 break;
641
642 default:
643 zStyle[0] = '\0';
644 break;
645 }
646 sprintf(zFont, "%d.%s", rFont.GetPointSize(), zFacename);
647 if (zWeight[0] != '\0')
648 {
649 strcat(zFont, " ");
650 strcat(zFont, zWeight);
651 }
652 if (zStyle[0] != '\0')
653 {
654 strcat(zFont, " ");
655 strcat(zFont, zStyle);
656 }
657 ::WinSetPresParam(hWnd, PP_FONTNAMESIZE, strlen(zFont) + 1, (PVOID)zFont);
f38374d0 658 }
cdf1e714 659 return(TRUE);
0e320a79
DW
660}
661
0367c1c0 662bool wxWindowOS2::SetCursor(
f38374d0
DW
663 const wxCursor& rCursor
664) // check if base implementation is OK
0e320a79 665{
f38374d0
DW
666 if ( !wxWindowBase::SetCursor(rCursor))
667 {
668 // no change
669 return FALSE;
670 }
671
19193a2c
KB
672 if ( m_cursor.Ok() ) {
673 HWND hWnd = GetHwnd();
674 POINTL vPoint;
675 RECTL vRect;
f38374d0 676
19193a2c
KB
677 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
678 ::WinQueryWindowRect(hWnd, &vRect);
f38374d0 679
19193a2c
KB
680 if (::WinPtInRect(vHabmain, &vRect, &vPoint) && !wxIsBusy())
681 {
682 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR());
683 }
f38374d0
DW
684 }
685 return TRUE;
0367c1c0 686} // end of wxWindowOS2::SetCursor
0e320a79 687
0367c1c0 688void wxWindowOS2::WarpPointer(
a885d89a
DW
689 int nXPos
690, int nYPos
691)
0e320a79 692{
a885d89a
DW
693 int nX = nXPos;
694 int nY = nYPos;
695 RECTL vRect;
696
697 ::WinQueryWindowRect(GetHwnd(), &vRect);
698 nX += vRect.xLeft;
699 nY += vRect.yBottom;
700
701 ::WinSetPointerPos(HWND_DESKTOP, (LONG)nX, (LONG)(nY));
0367c1c0 702} // end of wxWindowOS2::WarpPointer
0e320a79 703
cdf1e714 704#if WXWIN_COMPATIBILITY
0367c1c0 705void wxWindowOS2::OS2DeviceToLogical (float *x, float *y) const
0e320a79 706{
0e320a79 707}
cdf1e714 708#endif // WXWIN_COMPATIBILITY
0e320a79 709
cdf1e714
DW
710// ---------------------------------------------------------------------------
711// scrolling stuff
712// ---------------------------------------------------------------------------
0e320a79 713
cdf1e714 714#if WXWIN_COMPATIBILITY
0367c1c0 715void wxWindowOS2::SetScrollRange(
a885d89a
DW
716 int nOrient
717, int nRange
718, bool bRefresh
719)
0e320a79 720{
b7d8f285
DW
721 int nRange1 = nRange;
722 int nPageSize = GetScrollPage(nOrient);
723
724 if (nPpageSize > 1 && nRange > 0)
725 {
726 nRange1 += (nPageSize - 1);
727 }
728
729 if (nOrient == wxHORIZONTAL)
730 {
731 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETSCROLLBAR, (MPARAM)0, MPFROM2SHORT(0, (SHORT)nRange1));
732 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0);
733 }
734 else
735 {
736 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETSCROLLBAR, (MPARAM)0, MPFROM2SHORT(0, (SHORT)nRange1));
737 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0);
738 }
0367c1c0 739} // end of wxWindowOS2::SetScrollRange
0e320a79 740
0367c1c0 741void wxWindowOS2::SetScrollPage(
a885d89a
DW
742 int nOrient
743, int nPage
744, bool bRefresh
745)
0e320a79 746{
b7d8f285
DW
747 if (nOrient == wxHORIZONTAL )
748 m_nXThumbSize = nPage;
a885d89a 749 else
b7d8f285 750 m_nYThumbSize = nPage;
0367c1c0 751} // end of wxWindowOS2::SetScrollPage
0e320a79 752
0367c1c0 753int wxWindowOS2::OldGetScrollRange(
a885d89a
DW
754 int nOrient
755) const
0e320a79 756{
a885d89a
DW
757 MRESULT mRc;
758 HWND hWnd = GetHwnd();
0e320a79 759
a885d89a
DW
760 if (hWnd)
761 {
762 mRc = WinSendMsg(hWnd, SBM_QUERYRANGE, (MPARAM)0L, (MPARAM)0L);
763 return(SHORT2FROMMR(mRc));
764 }
765 return 0;
0367c1c0 766} // end of wxWindowOS2::OldGetScrollRange
a885d89a 767
0367c1c0 768int wxWindowOS2::GetScrollPage(
a885d89a
DW
769 int nOrient
770) const
0e320a79 771{
a885d89a 772 if (nOrient == wxHORIZONTAL)
05fc6c0a 773 return m_nXThumbSize;
a885d89a 774 else
05fc6c0a 775 return m_nYThumbSize;
0367c1c0 776} // end of wxWindowOS2::GetScrollPage
11e59d47 777#endif // WXWIN_COMPATIBILITY
0e320a79 778
0367c1c0 779int wxWindowOS2::GetScrollPos(
05fc6c0a
DW
780 int nOrient
781) const
0e320a79 782{
b7d8f285
DW
783 if (nOrient == wxHORIZONTAL)
784 return((int)::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
785 else
786 return((int)::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
0367c1c0 787} // end of wxWindowOS2::GetScrollPos
0e320a79 788
0367c1c0 789int wxWindowOS2::GetScrollRange(
05fc6c0a
DW
790 int nOrient
791) const
0e320a79 792{
05fc6c0a 793 MRESULT mr;
0e320a79 794
b7d8f285
DW
795 if (nOrient == wxHORIZONTAL)
796 mr = ::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
797 else
798 mr = ::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
05fc6c0a 799 return((int)SHORT2FROMMR(mr));
0367c1c0 800} // end of wxWindowOS2::GetScrollRange
05fc6c0a 801
0367c1c0 802int wxWindowOS2::GetScrollThumb(
05fc6c0a
DW
803 int nOrient
804) const
0e320a79 805{
b7d8f285
DW
806 if (nOrient == wxHORIZONTAL )
807 return m_nXThumbSize;
808 else
809 return m_nYThumbSize;
0367c1c0 810} // end of wxWindowOS2::GetScrollThumb
0e320a79 811
0367c1c0 812void wxWindowOS2::SetScrollPos(
05fc6c0a
DW
813 int nOrient
814, int nPos
19193a2c 815, bool WXUNUSED(bRefresh)
05fc6c0a 816)
0e320a79 817{
b7d8f285
DW
818 if (nOrient == wxHORIZONTAL )
819 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
820 else
821 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
19193a2c 822} // end of wxWindowOS2::SetScrollPos
0e320a79 823
0367c1c0 824void wxWindowOS2::SetScrollbar(
05fc6c0a
DW
825 int nOrient
826, int nPos
827, int nThumbVisible
828, int nRange
19193a2c 829, bool WXUNUSED(bRefresh)
05fc6c0a 830)
0e320a79 831{
1c84ee88
DW
832 int nOldRange = nRange - nThumbVisible;
833 int nRange1 = nOldRange;
834 int nPageSize = nThumbVisible;
835 SBCDATA vInfo;
836 HWND hWnd = GetHwnd();
e661fcd7 837 ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT;
1c84ee88
DW
838 RECTL vRect;
839
840 ::WinQueryWindowRect(hWnd, &vRect);
841 if (nPageSize > 1 && nRange > 0)
05fc6c0a 842 {
1c84ee88
DW
843 nRange1 += (nPageSize - 1);
844 }
845
846 vInfo.cb = sizeof(SBCDATA);
847 vInfo.posFirst = 0;
848 vInfo.posLast = (SHORT)nRange1;
849 vInfo.posThumb = nPos;
850
851 if (nOrient == wxHORIZONTAL )
852 {
853 ulStyle |= SBS_HORZ;
c8b5f745 854 if (m_hWndScrollBarHorz == 0L)
1c84ee88 855 {
b7d8f285
DW
856 //
857 // We create the scrollbars with the desktop so that they are not
858 // registered as child windows of the window in order that child
859 // windows may be scrolled without scrolling the scrollbars themselves!
860 //
e661fcd7 861 m_hWndScrollBarHorz = ::WinCreateWindow( hWnd
c8b5f745
DW
862 ,WC_SCROLLBAR
863 ,(PSZ)NULL
864 ,ulStyle
865 ,vRect.xLeft
866 ,vRect.yBottom
867 ,vRect.xRight - vRect.xLeft
868 ,20
869 ,hWnd
870 ,HWND_TOP
b7d8f285 871 ,FID_HORZSCROLL
c8b5f745
DW
872 ,&vInfo
873 ,NULL
874 );
1c84ee88
DW
875 }
876 else
877 {
c8b5f745
DW
878 RECTL vRect2;
879
880 //
881 // Only want to resize the scrollbar if it changes, otherwise
882 // we'd probably end up in a recursive loop until we crash the call stack
883 // because this method is called in a ScrolledWindow OnSize event and SWP_MOVE | SWP_SIZE
884 // generates those events.
885 //
886 ::WinQueryWindowRect(m_hWndScrollBarHorz, &vRect2);
887 if (!(vRect2.xLeft == vRect.xLeft &&
888 vRect2.xRight == vRect.xRight &&
889 vRect2.yBottom == vRect.yBottom &&
890 vRect2.yTop == vRect.yTop
891 ) )
892 {
893 ::WinSetWindowPos( m_hWndScrollBarHorz
894 ,HWND_TOP
895 ,vRect.xLeft
896 ,vRect.yBottom
897 ,vRect.xRight - vRect.xLeft
898 ,20
899 ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
900 );
901 }
902 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, (SHORT)nRange1));
2be39ac9 903 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0);
1c84ee88 904 }
05fc6c0a
DW
905 }
906 else
907 {
1c84ee88 908 ulStyle |= SBS_VERT;
c8b5f745 909 if (m_hWndScrollBarVert == 0L)
1c84ee88 910 {
e661fcd7 911 m_hWndScrollBarVert = ::WinCreateWindow( hWnd
c8b5f745
DW
912 ,WC_SCROLLBAR
913 ,(PSZ)NULL
914 ,ulStyle
915 ,vRect.xRight - 20
833615dd 916 ,vRect.yBottom + 20
c8b5f745 917 ,20
833615dd 918 ,vRect.yTop - (vRect.yBottom + 20)
c8b5f745
DW
919 ,hWnd
920 ,HWND_TOP
b7d8f285 921 ,FID_VERTSCROLL
c8b5f745
DW
922 ,&vInfo
923 ,NULL
924 );
1c84ee88
DW
925 }
926 else
927 {
c8b5f745
DW
928 RECTL vRect2;
929
930 //
931 // Only want to resize the scrollbar if it changes, otherwise
932 // we'd probably end up in a recursive loop until we crash the call stack
933 // because this method is called in a ScrolledWindow OnSize event and SWP_MOVE | SWP_SIZE
934 // generates those events.
935 //
936 ::WinQueryWindowRect(m_hWndScrollBarVert, &vRect2);
937 if (!(vRect2.xLeft == vRect.xLeft &&
938 vRect2.xRight == vRect.xRight &&
939 vRect2.yBottom == vRect.yBottom &&
940 vRect2.yTop == vRect.yTop
941 ) )
942 {
943 ::WinSetWindowPos( m_hWndScrollBarVert
944 ,HWND_TOP
945 ,vRect.xRight - 20
833615dd 946 ,vRect.yBottom + 20
c8b5f745 947 ,20
833615dd 948 ,vRect.yTop - (vRect.yBottom + 20)
c8b5f745
DW
949 ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
950 );
951 }
952 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, (SHORT)nRange1));
2be39ac9 953 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0);
1c84ee88 954 }
05fc6c0a
DW
955 m_nYThumbSize = nThumbVisible;
956 }
0367c1c0 957} // end of wxWindowOS2::SetScrollbar
0e320a79 958
0367c1c0 959void wxWindowOS2::ScrollWindow(
05fc6c0a
DW
960 int nDx
961, int nDy
962, const wxRect* pRect
963)
0e320a79 964{
b7d8f285 965 RECTL vRect;
05fc6c0a
DW
966 RECTL vRect2;
967
b7d8f285 968 nDy *= -1; // flip the sign of Dy as OS/2 is opposite wxWin.
05fc6c0a
DW
969 if (pRect)
970 {
971 vRect2.xLeft = pRect->x;
b7d8f285 972 vRect2.yTop = pRect->y + pRect->height;
05fc6c0a 973 vRect2.xRight = pRect->x + pRect->width;
b7d8f285 974 vRect2.yBottom = pRect->y;
05fc6c0a 975 }
e661fcd7
DW
976 else
977 {
978 ::WinQueryWindowRect(GetHwnd(), &vRect2);
979 ::WinQueryWindowRect(m_hWndScrollBarHorz, &vRect);
980 vRect2.yBottom += vRect.yTop - vRect.yBottom;
981 ::WinQueryWindowRect(m_hWndScrollBarVert, &vRect);
982 vRect2.xRight -= vRect.xRight - vRect.xLeft;
05fc6c0a 983
e661fcd7 984 }
05fc6c0a 985 if (pRect)
b7d8f285
DW
986 ::WinScrollWindow( GetHwnd()
987 ,(LONG)nDx
988 ,(LONG)nDy
989 ,&vRect2
990 ,NULL
991 ,NULLHANDLE
992 ,NULL
e661fcd7 993 ,SW_INVALIDATERGN
b7d8f285 994 );
05fc6c0a 995 else
b7d8f285
DW
996 ::WinScrollWindow( GetHwnd()
997 ,nDx
998 ,nDy
999 ,NULL
1000 ,NULL
1001 ,NULLHANDLE
1002 ,NULL
e661fcd7
DW
1003 ,SW_INVALIDATERGN
1004 );
1005
1006 //
1007 // Move the children
1008 wxWindowList::Node* pCurrent = GetChildren().GetFirst();
1009 SWP vSwp;
1010
1011 while (pCurrent)
1012 {
1013 wxWindow* pChildWin = pCurrent->GetData();
1014
cb71578c
DW
1015 if (pChildWin->GetHWND() != NULLHANDLE)
1016 {
1017 ::WinQueryWindowPos(pChildWin->GetHWND(), &vSwp);
1018 ::WinQueryWindowRect(pChildWin->GetHWND(), &vRect);
1019 if (pChildWin->GetHWND() == m_hWndScrollBarVert ||
1020 pChildWin->GetHWND() == m_hWndScrollBarHorz)
1021 {
1022 ::WinSetWindowPos( pChildWin->GetHWND()
1023 ,HWND_TOP
1024 ,vSwp.x + nDx
1025 ,vSwp.y + nDy
1026 ,0
1027 ,0
1028 ,SWP_MOVE | SWP_SHOW | SWP_ZORDER
1029 );
1030 }
1031 else
1032 {
1033 ::WinSetWindowPos( pChildWin->GetHWND()
1034 ,HWND_BOTTOM
1035 ,vSwp.x + nDx
1036 ,vSwp.y + nDy
1037 ,0
1038 ,0
1039 ,SWP_MOVE | SWP_ZORDER
1040 );
1041 ::WinInvalidateRect(pChildWin->GetHWND(), &vRect, FALSE);
1042 }
1043 }
e661fcd7
DW
1044 pCurrent = pCurrent->GetNext();
1045 }
0367c1c0 1046} // end of wxWindowOS2::ScrollWindow
0e320a79 1047
cdf1e714
DW
1048// ---------------------------------------------------------------------------
1049// subclassing
1050// ---------------------------------------------------------------------------
0e320a79 1051
0367c1c0 1052void wxWindowOS2::SubclassWin(
c86c44a0
DW
1053 WXHWND hWnd
1054)
0e320a79 1055{
05fc6c0a
DW
1056 HWND hwnd = (HWND)hWnd;
1057
776d87d5 1058 wxASSERT_MSG( !m_fnOldWndProc, wxT("subclassing window twice?") );
61243a51 1059 wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") );
542875a8 1060 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
0367c1c0 1061} // end of wxWindowOS2::SubclassWin
0e320a79 1062
0367c1c0 1063void wxWindowOS2::UnsubclassWin()
0e320a79 1064{
c86c44a0 1065 //
cdf1e714 1066 // Restore old Window proc
c86c44a0 1067 //
e604d44b 1068 HWND hwnd = GetHWND();
c86c44a0 1069
e604d44b 1070 if (m_hWnd)
cdf1e714 1071 {
61243a51 1072 wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") );
0e320a79 1073
e604d44b 1074 PFNWP fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP);
51c1d535 1075
c86c44a0 1076 if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc))
cdf1e714 1077 {
c86c44a0
DW
1078 WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc);
1079 m_fnOldWndProc = 0;
cdf1e714
DW
1080 }
1081 }
0367c1c0 1082} // end of wxWindowOS2::UnsubclassWin
0e320a79 1083
05fc6c0a 1084//
cdf1e714 1085// Make a Windows extended style from the given wxWindows window style
05fc6c0a 1086//
0367c1c0 1087WXDWORD wxWindowOS2::MakeExtendedStyle(
05fc6c0a
DW
1088 long lStyle
1089, bool bEliminateBorders
1090)
0e320a79 1091{
05fc6c0a 1092 //
008089f6
DW
1093 // Simply fill out with wxWindow extended styles. We'll conjure
1094 // something up in OS2Create and all window redrawing pieces later
05fc6c0a 1095 //
008089f6
DW
1096 WXDWORD dwStyle = 0;
1097
1098 if (lStyle & wxTRANSPARENT_WINDOW )
1099 dwStyle |= wxTRANSPARENT_WINDOW;
1100
1101 if (!bEliminateBorders)
1102 {
1103 if (lStyle & wxSUNKEN_BORDER)
1104 dwStyle |= wxSUNKEN_BORDER;
1105 if (lStyle & wxDOUBLE_BORDER)
1106 dwStyle |= wxDOUBLE_BORDER;
1107 if (lStyle & wxRAISED_BORDER )
1108 dwStyle |= wxRAISED_BORDER;
1109 if (lStyle & wxSTATIC_BORDER)
1110 dwStyle |= wxSTATIC_BORDER;
1111 }
1112 return dwStyle;
0367c1c0 1113} // end of wxWindowOS2::MakeExtendedStyle
cdf1e714 1114
c86c44a0 1115//
008089f6 1116// Determines whether simulated 3D effects or CTL3D should be used,
cdf1e714 1117// applying a default border style if required, and returning an extended
008089f6 1118// style to pass to OS2Create.
c86c44a0 1119//
0367c1c0 1120WXDWORD wxWindowOS2::Determine3DEffects(
c86c44a0 1121 WXDWORD dwDefaultBorderStyle
542875a8 1122, bool* pbWant3D
c86c44a0
DW
1123) const
1124{
542875a8
DW
1125 WXDWORD dwStyle = 0L;
1126
c86c44a0 1127 //
008089f6
DW
1128 // Native PM does not have any specialize 3D effects like WIN32 does,
1129 // so we have to try and invent them.
1130 //
1131
1132 //
1133 // If matches certain criteria, then assume no 3D effects
1134 // unless specifically requested (dealt with in MakeExtendedStyle)
1135 //
1136 if (!GetParent() ||
1137 !IsKindOf(CLASSINFO(wxControl)) ||
1138 (m_windowStyle & wxNO_BORDER)
1139 )
1140 {
1141 *pbWant3D = FALSE;
1142 return MakeExtendedStyle(m_windowStyle, FALSE);
1143 }
1144
1145 //
1146 // 1) App can specify global 3D effects
c86c44a0 1147 //
008089f6
DW
1148 *pbWant3D = wxTheApp->GetAuto3D();
1149
1150 //
1151 // 2) If the parent is being drawn with user colours, or simple border
1152 // specified, switch effects off.
1153 //
1154 if (GetParent() &&
1155 (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) ||
1156 (m_windowStyle & wxSIMPLE_BORDER)
1157 )
1158 *pbWant3D = FALSE;
1159
1160 //
1161 // 3) Control can override this global setting by defining
1162 // a border style, e.g. wxSUNKEN_BORDER
1163 //
1164 if ((m_windowStyle & wxDOUBLE_BORDER) ||
1165 (m_windowStyle & wxRAISED_BORDER) ||
1166 (m_windowStyle & wxSTATIC_BORDER) ||
1167 (m_windowStyle & wxSUNKEN_BORDER)
1168 )
1169 *pbWant3D = TRUE;
1170
1171 dwStyle = MakeExtendedStyle( m_windowStyle
1172 ,FALSE
1173 );
1174
1175 //
1176 // If we want 3D, but haven't specified a border here,
1177 // apply the default border style specified.
1178 //
1179 if (dwDefaultBorderStyle && (*pbWant3D) &&
1180 !((m_windowStyle & wxDOUBLE_BORDER) ||
1181 (m_windowStyle & wxRAISED_BORDER) ||
1182 (m_windowStyle & wxSTATIC_BORDER) ||
1183 (m_windowStyle & wxSIMPLE_BORDER)
1184 )
1185 )
1186 dwStyle |= dwDefaultBorderStyle;
c86c44a0 1187 return dwStyle;
0367c1c0 1188} // end of wxWindowOS2::Determine3DEffects
cdf1e714
DW
1189
1190#if WXWIN_COMPATIBILITY
0367c1c0 1191void wxWindowOS2::OnCommand(
c86c44a0
DW
1192 wxWindow& rWin
1193, wxCommandEvent& rEvent
1194)
cdf1e714 1195{
c86c44a0
DW
1196 if (GetEventHandler()->ProcessEvent(rEvent))
1197 return;
1198 if (m_parent)
1199 m_parent->GetEventHandler()->OnCommand( rWin
1200 ,rEvent
1201 );
0367c1c0 1202} // end of wxWindowOS2::OnCommand
cdf1e714 1203
0367c1c0 1204wxObject* wxWindowOS2::GetChild(
c86c44a0
DW
1205 int nNumber
1206) const
cdf1e714 1207{
c86c44a0
DW
1208 //
1209 // Return a pointer to the Nth object in the Panel
1210 //
1211 wxNode* pNode = GetChildren().First();
1212 int n = nNumber;
cdf1e714 1213
c86c44a0
DW
1214 while (pNode && n--)
1215 pNode = pNode->Next();
1216 if (pNode)
1217 {
1218 wxObject* pObj = (wxObject*)pNode->Data();
1219 return(pObj);
1220 }
1221 else
1222 return NULL;
0367c1c0 1223} // end of wxWindowOS2::GetChild
cdf1e714
DW
1224
1225#endif // WXWIN_COMPATIBILITY
1226
c86c44a0 1227//
cdf1e714 1228// Setup background and foreground colours correctly
c86c44a0 1229//
0367c1c0 1230void wxWindowOS2::SetupColours()
cdf1e714
DW
1231{
1232 if ( GetParent() )
1233 SetBackgroundColour(GetParent()->GetBackgroundColour());
0367c1c0 1234} // end of wxWindowOS2::SetupColours
cdf1e714 1235
0367c1c0 1236void wxWindowOS2::OnIdle(
19193a2c 1237 wxIdleEvent& WXUNUSED(rEvent)
c86c44a0 1238)
cdf1e714 1239{
c86c44a0
DW
1240 //
1241 // Check if we need to send a LEAVE event
1242 //
1243 if (m_bMouseInWindow)
1244 {
1245 POINTL vPoint;
cdf1e714 1246
c86c44a0
DW
1247 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
1248 if (::WinWindowFromPoint(HWND_DESKTOP, &vPoint, FALSE) != (HWND)GetHwnd())
1249 {
1250 //
1251 // Generate a LEAVE event
1252 //
1253 m_bMouseInWindow = FALSE;
1254
1255 //
1256 // Unfortunately the mouse button and keyboard state may have changed
1257 // by the time the OnIdle function is called, so 'state' may be
1258 // meaningless.
1259 //
1260 int nState = 0;
1261
1262 if (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) != 0)
1263 nState |= VK_SHIFT;
542875a8 1264 if (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) != 0);
c86c44a0
DW
1265 nState |= VK_CTRL;
1266
1267 wxMouseEvent rEvent(wxEVT_LEAVE_WINDOW);
1268
1269 InitMouseEvent( rEvent
1270 ,vPoint.x
1271 ,vPoint.y
1272 ,nState
1273 );
542875a8 1274 (void)GetEventHandler()->ProcessEvent(rEvent);
c86c44a0
DW
1275 }
1276 }
1277 UpdateWindowUI();
0367c1c0 1278} // end of wxWindowOS2::OnIdle
c86c44a0
DW
1279
1280//
cdf1e714 1281// Set this window to be the child of 'parent'.
c86c44a0 1282//
0367c1c0 1283bool wxWindowOS2::Reparent(
c86c44a0
DW
1284 wxWindow* pParent
1285)
cdf1e714 1286{
c86c44a0 1287 if (!wxWindowBase::Reparent(pParent))
cdf1e714 1288 return FALSE;
c86c44a0
DW
1289
1290 HWND hWndChild = GetHwnd();
1291 HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
1292
1293 ::WinSetParent(hWndChild, hWndParent, TRUE);
1294 return TRUE;
0367c1c0 1295} // end of wxWindowOS2::Reparent
cdf1e714 1296
0367c1c0 1297void wxWindowOS2::Clear()
cdf1e714 1298{
19193a2c 1299 wxClientDC vDc((wxWindow*)this);
c86c44a0
DW
1300 wxBrush vBrush( GetBackgroundColour()
1301 ,wxSOLID
1302 );
1303
1304 vDc.SetBackground(vBrush);
1305 vDc.Clear();
0367c1c0 1306} // end of wxWindowOS2::Clear
cdf1e714 1307
0367c1c0 1308void wxWindowOS2::Refresh(
c86c44a0
DW
1309 bool bEraseBack
1310, const wxRect* pRect
1311)
cdf1e714 1312{
c86c44a0
DW
1313 HWND hWnd = GetHwnd();
1314
1315 if (hWnd)
1316 {
1317 if (pRect)
1318 {
1319 RECTL vOs2Rect;
1320
1321 vOs2Rect.xLeft = pRect->x;
542875a8 1322 vOs2Rect.yTop = pRect->y;
c86c44a0
DW
1323 vOs2Rect.xRight = pRect->x + pRect->width;
1324 vOs2Rect.yBottom = pRect->y + pRect->height;
1325
1326 ::WinInvalidateRect(hWnd, &vOs2Rect, bEraseBack);
1327 }
1328 else
1329 ::WinInvalidateRect(hWnd, NULL, bEraseBack);
1330 }
0367c1c0 1331} // end of wxWindowOS2::Refresh
cdf1e714
DW
1332
1333// ---------------------------------------------------------------------------
1334// drag and drop
1335// ---------------------------------------------------------------------------
1336
1337#if wxUSE_DRAG_AND_DROP
0367c1c0 1338void wxWindowOS2::SetDropTarget(
c86c44a0
DW
1339 wxDropTarget* pDropTarget
1340)
cdf1e714 1341{
542875a8 1342 if (m_dropTarget != 0)
c86c44a0
DW
1343 {
1344 m_dropTarget->Revoke(m_hWnd);
1345 delete m_dropTarget;
1346 }
1347 m_dropTarget = pDropTarget;
1348 if (m_dropTarget != 0)
1349 m_dropTarget->Register(m_hWnd);
0367c1c0 1350} // end of wxWindowOS2::SetDropTarget
cdf1e714
DW
1351#endif
1352
c86c44a0 1353//
cdf1e714
DW
1354// old style file-manager drag&drop support: we retain the old-style
1355// DragAcceptFiles in parallel with SetDropTarget.
c86c44a0 1356//
0367c1c0 1357void wxWindowOS2::DragAcceptFiles(
c86c44a0
DW
1358 bool bAccept
1359)
cdf1e714 1360{
c86c44a0
DW
1361 HWND hWnd = GetHwnd();
1362
1363 if (hWnd && bAccept)
542875a8 1364 ::DrgAcceptDroppedFiles(hWnd, NULL, NULL, DO_COPY, 0L);
0367c1c0 1365} // end of wxWindowOS2::DragAcceptFiles
cdf1e714
DW
1366
1367// ----------------------------------------------------------------------------
1368// tooltips
1369// ----------------------------------------------------------------------------
1370
1371#if wxUSE_TOOLTIPS
1372
0367c1c0 1373void wxWindowOS2::DoSetToolTip(
c86c44a0
DW
1374 wxToolTip* pTooltip
1375)
cdf1e714 1376{
c86c44a0 1377 wxWindowBase::DoSetToolTip(pTooltip);
cdf1e714 1378
542875a8 1379 if (m_tooltip)
cdf1e714 1380 m_tooltip->SetWindow(this);
0367c1c0 1381} // end of wxWindowOS2::DoSetToolTip
cdf1e714
DW
1382
1383#endif // wxUSE_TOOLTIPS
1384
1385// ---------------------------------------------------------------------------
1386// moving and resizing
1387// ---------------------------------------------------------------------------
1388
1389// Get total size
0367c1c0 1390void wxWindowOS2::DoGetSize(
a7ef993c
DW
1391 int* pWidth
1392, int* pHeight
1393) const
cdf1e714 1394{
a7ef993c
DW
1395 HWND hWnd = GetHwnd();
1396 RECTL vRect;
c86c44a0 1397
a7ef993c
DW
1398 ::WinQueryWindowRect(hWnd, &vRect);
1399
1400 if (pWidth)
1401 *pWidth = vRect.xRight - vRect.xLeft;
1402 if (pHeight )
1403 // OS/2 PM is backwards from windows
1404 *pHeight = vRect.yTop - vRect.yBottom;
0367c1c0 1405} // end of wxWindowOS2::DoGetSize
cdf1e714 1406
0367c1c0 1407void wxWindowOS2::DoGetPosition(
a7ef993c
DW
1408 int* pX
1409, int* pY
1410) const
cdf1e714 1411{
a7ef993c 1412 HWND hWnd = GetHwnd();
8330166c 1413 SWP vSwp;
a7ef993c 1414 POINTL vPoint;
8330166c 1415 wxWindow* pParent = GetParent();
c86c44a0 1416
8330166c
DW
1417 //
1418 // It would seem that WinQueryWindowRect would be the correlary to
1419 // the WIN32 WinGetRect, but unlike WinGetRect which returns the window
1420 // origin position in screen coordinates, WinQueryWindowRect returns it
1421 // relative to itself, i.e. (0,0). To get the same under PM we must
1422 // us WinQueryWindowPos. This call, unlike the WIN32 call, however,
1423 // returns a position relative to it's parent, so no parent adujstments
1424 // are needed under OS/2. Also, windows should be created using
1425 // wxWindow coordinates, i.e 0,0 is the TOP left so vSwp will already
1426 // reflect that.
1427 //
1428 ::WinQueryWindowPos(hWnd, &vSwp);
c86c44a0 1429
8330166c
DW
1430 vPoint.x = vSwp.x;
1431 vPoint.y = vSwp.y;
c86c44a0 1432
a7ef993c 1433 //
8330166c
DW
1434 // We may be faking the client origin. So a window that's really at (0,
1435 // 30) may appear (to wxWin apps) to be at (0, 0).
a7ef993c 1436 //
8330166c 1437 if (pParent)
c86c44a0 1438 {
8330166c 1439 wxPoint vPt(pParent->GetClientAreaOrigin());
a7ef993c 1440
8330166c
DW
1441 vPoint.x -= vPt.x;
1442 vPoint.y -= vPt.y;
c86c44a0
DW
1443 }
1444
a7ef993c
DW
1445 if (pX)
1446 *pX = vPoint.x;
542875a8 1447 if (pY)
a7ef993c 1448 *pY = vPoint.y;
0367c1c0 1449} // end of wxWindowOS2::DoGetPosition
cdf1e714 1450
0367c1c0 1451void wxWindowOS2::DoScreenToClient(
a7ef993c
DW
1452 int* pX
1453, int* pY
1454) const
cdf1e714 1455{
a7ef993c 1456 HWND hWnd = GetHwnd();
8330166c 1457 SWP vSwp;
542875a8 1458
8330166c 1459 ::WinQueryWindowPos(hWnd, &vSwp);
cdf1e714 1460
a7ef993c 1461 if (pX)
8330166c 1462 *pX += vSwp.x;
a7ef993c 1463 if (pY)
8330166c 1464 *pY += vSwp.y;
0367c1c0 1465} // end of wxWindowOS2::DoScreenToClient
a7ef993c 1466
0367c1c0 1467void wxWindowOS2::DoClientToScreen(
a7ef993c
DW
1468 int* pX
1469, int* pY
1470) const
cdf1e714 1471{
a7ef993c 1472 HWND hWnd = GetHwnd();
8330166c 1473 SWP vSwp;
19193a2c 1474
8330166c 1475 ::WinQueryWindowPos(hWnd, &vSwp);
c86c44a0 1476
a7ef993c 1477 if (pX)
8330166c 1478 *pX += vSwp.x;
a7ef993c 1479 if (pY)
8330166c 1480 *pY += vSwp.y;
0367c1c0 1481} // end of wxWindowOS2::DoClientToScreen
cdf1e714 1482
a7ef993c 1483//
cdf1e714 1484// Get size *available for subwindows* i.e. excluding menu bar etc.
a7ef993c
DW
1485// Must be a frame type window
1486//
0367c1c0 1487void wxWindowOS2::DoGetClientSize(
a7ef993c
DW
1488 int* pWidth
1489, int* pHeight
1490) const
cdf1e714 1491{
a7ef993c
DW
1492 HWND hWnd = GetHwnd();
1493 HWND hWndClient;
1494 RECTL vRect;
1495
833615dd
DW
1496 if (IsKindOf(CLASSINFO(wxFrame)))
1497 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
1498 else
1499 hWndClient = NULLHANDLE;
51c1d535
DW
1500 if( hWndClient == NULLHANDLE)
1501 ::WinQueryWindowRect(GetHwnd(), &vRect);
1502 else
1503 ::WinQueryWindowRect(hWndClient, &vRect);
a7ef993c 1504
542875a8 1505 if (pWidth)
a7ef993c 1506 *pWidth = vRect.xRight;
542875a8 1507 if (pHeight)
a7ef993c 1508 *pHeight = vRect.yTop;
0367c1c0 1509} // end of wxWindowOS2::DoGetClientSize
cdf1e714 1510
0367c1c0 1511void wxWindowOS2::DoMoveWindow(
a7ef993c
DW
1512 int nX
1513, int nY
1514, int nWidth
1515, int nHeight
1516)
cdf1e714 1517{
39c26ef2
DW
1518 RECTL vRect;
1519 HWND hParent;
1520 wxWindow* pParent = GetParent();
1521
1522 if (pParent)
987da0d4 1523 {
39c26ef2 1524 hParent = GetWinHwnd(pParent);
987da0d4
DW
1525 if (pParent->IsKindOf(CLASSINFO(wxFrame)))
1526 {
1527 if (IsKindOf(CLASSINFO(wxStatusBar)) ||
1528 IsKindOf(CLASSINFO(wxMenuBar)) ||
1529 IsKindOf(CLASSINFO(wxToolBar))
1530 )
1531 nY = pParent->GetSize().y - (nY + nHeight);
1532 else
1533 nY = pParent->GetClientSize().y - (nY + nHeight);
1534 }
1535 else
1536 nY = pParent->GetSize().y - (nY + nHeight);
1537 }
39c26ef2 1538 else
c86c44a0 1539 {
987da0d4
DW
1540 RECTL vRect;
1541
1542 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
1543 nY = vRect.yTop - (nY + nHeight);
1544 }
1545 ::WinSetWindowPos( GetHwnd()
1546 ,HWND_TOP
1547 ,(LONG)nX
1548 ,(LONG)nY
1549 ,(LONG)nWidth
1550 ,(LONG)nHeight
1551 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
1552 );
0367c1c0 1553} // end of wxWindowOS2::DoMoveWindow
cdf1e714 1554
c86c44a0
DW
1555//
1556// Set the size of the window: if the dimensions are positive, just use them,
cdf1e714
DW
1557// but if any of them is equal to -1, it means that we must find the value for
1558// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1559// which case -1 is a valid value for x and y)
1560//
1561// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1562// the width/height to best suit our contents, otherwise we reuse the current
1563// width/height
c86c44a0 1564//
0367c1c0 1565void wxWindowOS2::DoSetSize(
a7ef993c
DW
1566 int nX
1567, int nY
1568, int nWidth
1569, int nHeight
1570, int nSizeFlags
1571)
cdf1e714 1572{
a7ef993c
DW
1573 //
1574 // Get the current size and position...
1575 //
1576 int nCurrentX;
1577 int nCurrentY;
1578 int nCurrentWidth;
1579 int nCurrentHeight;
542875a8 1580 wxSize vSize(-1, -1);
a7ef993c 1581
19193a2c
KB
1582 GetPosition(&nCurrentX, &nCurrentY);
1583 GetSize(&nCurrentWidth, &nCurrentHeight);
c86c44a0
DW
1584
1585 // ... and don't do anything (avoiding flicker) if it's already ok
19193a2c
KB
1586 if (nX == nCurrentX && nY == nCurrentY &&
1587 nWidth == nCurrentWidth && nHeight == nCurrentHeight)
c86c44a0
DW
1588 {
1589 return;
1590 }
1591
a7ef993c
DW
1592 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1593 nX = nCurrentX;
542875a8 1594 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
a7ef993c 1595 nY = nCurrentY;
c86c44a0 1596
19193a2c 1597 AdjustForParentClientOrigin(nX, nY, nSizeFlags);
c86c44a0 1598
a7ef993c 1599 if (nWidth == -1)
c86c44a0 1600 {
a7ef993c 1601 if (nSizeFlags & wxSIZE_AUTO_WIDTH)
c86c44a0 1602 {
a7ef993c
DW
1603 vSize = DoGetBestSize();
1604 nWidth = vSize.x;
c86c44a0
DW
1605 }
1606 else
1607 {
a7ef993c
DW
1608 //
1609 // Just take the current one
1610 //
1611 nWidth = nCurrentWidth;
c86c44a0
DW
1612 }
1613 }
1614
a7ef993c 1615 if (nHeight == -1)
c86c44a0 1616 {
a7ef993c 1617 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
c86c44a0 1618 {
a7ef993c 1619 if (vSize.x == -1)
c86c44a0 1620 {
a7ef993c 1621 vSize = DoGetBestSize();
c86c44a0 1622 }
a7ef993c 1623 nHeight = vSize.y;
c86c44a0
DW
1624 }
1625 else
1626 {
1627 // just take the current one
a7ef993c 1628 nHeight = nCurrentHeight;
c86c44a0
DW
1629 }
1630 }
1631
a7ef993c
DW
1632 DoMoveWindow( nX
1633 ,nY
1634 ,nWidth
1635 ,nHeight
1636 );
0367c1c0 1637} // end of wxWindowOS2::DoSetSize
cdf1e714 1638
0367c1c0 1639void wxWindowOS2::DoSetClientSize(
a7ef993c
DW
1640 int nWidth
1641, int nHeight
1642)
cdf1e714 1643{
a7ef993c
DW
1644 wxWindow* pParent = GetParent();
1645 HWND hWnd = GetHwnd();
1646 HWND hParentWnd = (HWND)0;
8330166c 1647 POINTL vPoint;
a7ef993c 1648 RECTL vRect;
8330166c
DW
1649 RECTL vRect2;
1650 RECTL vRect3;
1651 HWND hClientWnd = (HWND)0;
c86c44a0 1652
8330166c 1653 hClientWnd = ::WinWindowFromID(hWnd, FID_CLIENT);
a7ef993c 1654 ::WinQueryWindowRect(hClientWnd, &vRect2);
a7ef993c
DW
1655 ::WinQueryWindowRect(hWnd, &vRect);
1656 ::WinQueryWindowRect(hParentWnd, &vRect3);
8330166c 1657
a7ef993c
DW
1658 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
1659 int nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
c86c44a0 1660
a7ef993c
DW
1661 vPoint.x = vRect2.xLeft;
1662 vPoint.y = vRect2.yBottom;
1663 if (pParent)
8330166c 1664 {
a7ef993c 1665 vPoint.x -= vRect3.xLeft;
542875a8 1666 vPoint.y -= vRect3.yBottom;
c86c44a0 1667 }
19193a2c
KB
1668
1669 DoMoveWindow(vPoint.x, vPoint.y, nActualWidth, nActualHeight);
1670
1671 wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
a7ef993c
DW
1672 vEvent.SetEventObject(this);
1673 GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 1674} // end of wxWindowOS2::DoSetClientSize
cdf1e714 1675
0367c1c0 1676wxPoint wxWindowOS2::GetClientAreaOrigin() const
cdf1e714
DW
1677{
1678 return wxPoint(0, 0);
0367c1c0 1679} // end of wxWindowOS2::GetClientAreaOrigin
cdf1e714 1680
cdf1e714
DW
1681// ---------------------------------------------------------------------------
1682// text metrics
1683// ---------------------------------------------------------------------------
1684
0367c1c0 1685int wxWindowOS2::GetCharHeight() const
cdf1e714 1686{
a7ef993c
DW
1687 HPS hPs;
1688 FONTMETRICS vFontMetrics;
cdf1e714 1689
a7ef993c
DW
1690 hPs = ::WinGetPS(GetHwnd());
1691
542875a8 1692 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1693 {
1694 ::WinReleasePS(hPs);
a7ef993c 1695 return (0);
b7084589 1696 }
a7ef993c 1697 ::WinReleasePS(hPs);
b7084589 1698 return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender);
0367c1c0 1699} // end of wxWindowOS2::GetCharHeight
a7ef993c 1700
0367c1c0 1701int wxWindowOS2::GetCharWidth() const
cdf1e714 1702{
542875a8
DW
1703 HPS hPs;
1704 FONTMETRICS vFontMetrics;
1705
a7ef993c 1706 hPs = ::WinGetPS(GetHwnd());
cdf1e714 1707
542875a8 1708 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1709 {
1710 ::WinReleasePS(hPs);
a7ef993c 1711 return (0);
b7084589 1712 }
a7ef993c 1713 ::WinReleasePS(hPs);
b7084589 1714 return(vFontMetrics.lAveCharWidth);
0367c1c0 1715} // end of wxWindowOS2::GetCharWidth
a7ef993c 1716
0367c1c0 1717void wxWindowOS2::GetTextExtent(
a7ef993c
DW
1718 const wxString& rString
1719, int* pX
1720, int* pY
1721, int* pDescent
1722, int* pExternalLeading
1723, const wxFont* pTheFont
1724) const
cdf1e714 1725{
987da0d4
DW
1726 POINTL avPoint[TXTBOX_COUNT];
1727 POINTL vPtMin;
1728 POINTL vPtMax;
1729 int i;
1730 int l;
1731 FONTMETRICS vFM; // metrics structure
1732 BOOL bRc;
1733 char* pStr;
1734 ERRORID vErrorCode; // last error id code
1735 HPS hPS;
19193a2c 1736
a7ef993c 1737
987da0d4 1738 hPS = ::WinGetPS(GetHwnd());
a7ef993c 1739
987da0d4
DW
1740 l = rString.Length();
1741 if (l > 0L)
1742 {
1743 pStr = (PCH)rString.c_str();
a7ef993c 1744
987da0d4
DW
1745 //
1746 // In world coordinates.
1747 //
1748 bRc = ::GpiQueryTextBox( hPS
1749 ,l
1750 ,pStr
1751 ,TXTBOX_COUNT // return maximum information
1752 ,avPoint // array of coordinates points
1753 );
1754 if (bRc)
1755 {
1756 vPtMin.x = avPoint[0].x;
1757 vPtMax.x = avPoint[0].x;
1758 vPtMin.y = avPoint[0].y;
1759 vPtMax.y = avPoint[0].y;
1760 for (i = 1; i < 4; i++)
1761 {
1762 if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
1763 if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
1764 if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
1765 if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
1766 }
1767 bRc = ::GpiQueryFontMetrics( hPS
1768 ,sizeof(FONTMETRICS)
1769 ,&vFM
1770 );
1771 if (!bRc)
1772 {
1773 vPtMin.x = 0;
1774 vPtMin.y = 0;
1775 vPtMax.x = 0;
1776 vPtMax.y = 0;
1777 }
1778 }
1779 else
1780 {
1781 vPtMin.x = 0;
1782 vPtMin.y = 0;
1783 vPtMax.x = 0;
1784 vPtMax.y = 0;
1785 }
1786 }
1787 else
a7ef993c 1788 {
987da0d4
DW
1789 vPtMin.x = 0;
1790 vPtMin.y = 0;
1791 vPtMax.x = 0;
1792 vPtMax.y = 0;
a7ef993c 1793 }
987da0d4
DW
1794 if (pX)
1795 *pX = (vPtMax.x - vPtMin.x + 1);
1796 if (pY)
1797 *pY = (vPtMax.y - vPtMin.y + 1);
1798 if (pDescent)
1799 {
1800 if (bRc)
1801 *pDescent = vFM.lMaxDescender;
1802 else
1803 *pDescent = 0;
1804 }
1805 if (pExternalLeading)
1806 {
1807 if (bRc)
1808 *pExternalLeading = vFM.lExternalLeading;
1809 else
1810 *pExternalLeading = 0;
1811 }
1812 ::WinReleasePS(hPS);
1813} // end of wxWindow::GetTextExtent
cdf1e714
DW
1814
1815#if wxUSE_CARET && WXWIN_COMPATIBILITY
1816// ---------------------------------------------------------------------------
1817// Caret manipulation
1818// ---------------------------------------------------------------------------
1819
0367c1c0 1820void wxWindowOS2::CreateCaret(
a7ef993c
DW
1821 int nWidth
1822, int nHeight
1823)
cdf1e714 1824{
a7ef993c
DW
1825 SetCaret(new wxCaret( this
1826 ,nWidth
1827 ,nHeight
1828 ));
0367c1c0 1829} // end of wxWindowOS2::CreateCaret
a7ef993c 1830
0367c1c0 1831void wxWindowOS2::CreateCaret(
a7ef993c
DW
1832 const wxBitmap* pBitmap
1833)
cdf1e714 1834{
a7ef993c 1835 wxFAIL_MSG("not implemented");
0367c1c0 1836} // end of wxWindowOS2::CreateCaret
cdf1e714 1837
0367c1c0 1838void wxWindowOS2::ShowCaret(
a7ef993c
DW
1839 bool bShow
1840)
cdf1e714 1841{
a7ef993c
DW
1842 wxCHECK_RET( m_caret, "no caret to show" );
1843
1844 m_caret->Show(bShow);
0367c1c0 1845} // end of wxWindowOS2::ShowCaret
cdf1e714 1846
0367c1c0 1847void wxWindowOS2::DestroyCaret()
cdf1e714 1848{
a7ef993c 1849 SetCaret(NULL);
0367c1c0 1850} // end of wxWindowOS2::DestroyCaret
cdf1e714 1851
0367c1c0 1852void wxWindowOS2::SetCaretPos(
a7ef993c
DW
1853 int nX
1854, int nY)
cdf1e714 1855{
a7ef993c
DW
1856 wxCHECK_RET( m_caret, "no caret to move" );
1857
1858 m_caret->Move( nX
1859 ,nY
1860 );
0367c1c0 1861} // end of wxWindowOS2::SetCaretPos
cdf1e714 1862
0367c1c0 1863void wxWindowOS2::GetCaretPos(
a7ef993c
DW
1864 int* pX
1865, int* pY
1866) const
cdf1e714 1867{
a7ef993c
DW
1868 wxCHECK_RET( m_caret, "no caret to get position of" );
1869
1870 m_caret->GetPosition( pX
1871 ,pY
1872 );
0367c1c0 1873} // end of wxWindowOS2::GetCaretPos
cdf1e714
DW
1874
1875#endif //wxUSE_CARET
1876
1877// ---------------------------------------------------------------------------
1878// popup menu
1879// ---------------------------------------------------------------------------
19193a2c
KB
1880//
1881#if wxUSE_MENUS_NATIVE
3febf684
DW
1882static void wxYieldForCommandsOnly()
1883{
1884 //
1885 // Peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
1886 // want to process it here)
1887 //
1888 QMSG vMsg;
1889
19193a2c
KB
1890 while (::WinPeekMsg(vHabmain, &vMsg, (HWND)0, WM_COMMAND,
1891 WM_COMMAND,PM_REMOVE) && vMsg.msg != WM_QUIT)
3febf684
DW
1892 {
1893 wxTheApp->DoMessage((WXMSG*)&vMsg);
1894 }
1895}
19193a2c 1896#endif // wxUSE_MENUS_NATIVE
3febf684 1897
19193a2c 1898#if wxUSE_MENUS_NATIVE
0367c1c0 1899bool wxWindowOS2::DoPopupMenu(
61243a51
DW
1900 wxMenu* pMenu
1901, int nX
1902, int nY
1903)
cdf1e714 1904{
61243a51
DW
1905 HWND hWnd = GetHwnd();
1906 HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
1907 HWND hMenu = GetHmenuOf(pMenu);
1908
1909 pMenu->SetInvokingWindow(this);
1910 pMenu->UpdateUI();
1911
1912 DoClientToScreen( &nX
1913 ,&nY
1914 );
1915 wxCurrentPopupMenu = pMenu;
1916
1917 ::WinPopupMenu( hWndParent
1918 ,hWnd
1919 ,hMenu
1920 ,nX
1921 ,nY
1922 ,0L
1923 ,PU_MOUSEBUTTON2DOWN | PU_MOUSEBUTTON2 | PU_KEYBOARD
1924 );
3febf684 1925 // we need to do it righ now as otherwise the events are never going to be
19193a2c 1926 // sent to wxCurrentPopupMenu from ;()
3febf684
DW
1927 //
1928 // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
1929 // help and we'd still need wxYieldForCommandsOnly() as the menu may be
1930 // destroyed as soon as we return (it can be a local variable in the caller
1931 // for example) and so we do need to process the event immediately
1932 wxYieldForCommandsOnly();
61243a51
DW
1933 wxCurrentPopupMenu = NULL;
1934
1935 pMenu->SetInvokingWindow(NULL);
1936 return TRUE;
0367c1c0 1937} // end of wxWindowOS2::DoPopupMenu
19193a2c 1938#endif // wxUSE_MENUS_NATIVE
cdf1e714
DW
1939
1940// ===========================================================================
1941// pre/post message processing
1942// ===========================================================================
1943
0367c1c0 1944MRESULT wxWindowOS2::OS2DefWindowProc(
61243a51
DW
1945 WXUINT uMsg
1946, WXWPARAM wParam
1947, WXLPARAM lParam
1948)
cdf1e714 1949{
61243a51 1950 if (m_fnOldWndProc)
19193a2c 1951 return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
61243a51 1952 else
19193a2c 1953 return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
0367c1c0 1954} // end of wxWindowOS2::OS2DefWindowProc
cdf1e714 1955
0367c1c0 1956bool wxWindowOS2::OS2ProcessMessage(
61243a51
DW
1957 WXMSG* pMsg
1958)
cdf1e714 1959{
19193a2c
KB
1960// wxUniversal implements tab traversal itself
1961#ifndef __WXUNIVERSAL__
61243a51
DW
1962 QMSG* pQMsg = (QMSG*)pMsg;
1963
1964 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
1965 {
1966 //
1967 // Intercept dialog navigation keys
1968 //
1969 bool bProcess = TRUE;
1970 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
1971
1972 if (uKeyFlags & KC_KEYUP)
1973 bProcess = FALSE;
1974
1975 if (uKeyFlags & KC_ALT)
1976 bProcess = FALSE;
1977
1978 if (!(uKeyFlags & KC_VIRTUALKEY))
1979 bProcess = FALSE;
1980
1981 if (bProcess)
1982 {
1983 bool bCtrlDown = IsCtrlDown();
1984 bool bShiftDown = IsShiftDown();
1985
1986 //
1987 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
1988 // don't process it if it's the case (except for Ctrl-Tab/Enter
1989 // combinations which are always processed)
1990 //
1991 ULONG ulDlgCode = 0;
1992
1993 if (!bCtrlDown)
1994 {
1995 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
1996 }
1997
1998 bool bForward = TRUE;
1999 bool bWindowChange = FALSE;
2000
2001 switch (SHORT2FROMMP(pQMsg->mp2))
2002 {
2003 //
2004 // Going to make certain assumptions about specific types of controls
2005 // here, so we may have to alter some things later if they prove invalid
2006 //
2007 case VK_TAB:
2008 //
2009 // Shift tabl will always be a nav-key but tabs may be wanted
2010 //
2011 if (!bShiftDown)
2012 {
2013 bProcess = FALSE;
2014 }
2015 else
2016 {
2017 //
2018 // Entry Fields want tabs for themselve usually
2019 //
2020 switch (ulDlgCode)
2021 {
2022 case DLGC_ENTRYFIELD:
2023 case DLGC_MLE:
2024 bProcess = TRUE;
2025 break;
2026
2027 default:
2028 bProcess = FALSE;
2029 }
2030
2031 //
2032 // Ctrl-Tab cycles thru notebook pages
2033 //
2034 bWindowChange = bCtrlDown;
2035 bForward = !bShiftDown;
2036 }
2037 break;
2038
2039 case VK_UP:
2040 case VK_LEFT:
2041 if (bCtrlDown)
2042 bProcess = FALSE;
2043 else
2044 bForward = FALSE;
2045 break;
2046
2047 case VK_DOWN:
2048 case VK_RIGHT:
2049 if (bCtrlDown)
2050 bProcess = FALSE;
2051 break;
2052
2053 case VK_ENTER:
2054 {
2055 if (bCtrlDown)
2056 {
2057 //
2058 // ctrl-enter is not processed
2059 //
2060 return FALSE;
2061 }
2062 else if (ulDlgCode & DLGC_BUTTON)
2063 {
2064 //
2065 // buttons want process Enter themselevs
2066 //
2067 bProcess = FALSE;
2068 }
2069 else
2070 {
1bcfc0e1
DW
2071 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
2072 ,wxButton
2073 );
61243a51
DW
2074
2075 if (pBtn && pBtn->IsEnabled())
2076 {
2077 //
2078 // If we do have a default button, do press it
2079 //
2080 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
2081 return TRUE;
2082 }
2083 // else: but if it does not it makes sense to make
2084 // it work like a TAB - and that's what we do.
2085 // Note that Ctrl-Enter always works this way.
2086 }
2087 }
2088 break;
2089
2090 default:
2091 bProcess = FALSE;
2092 }
2093
2094 if (bProcess)
2095 {
2096 wxNavigationKeyEvent vEvent;
2097
2098 vEvent.SetDirection(bForward);
2099 vEvent.SetWindowChange(bWindowChange);
2100 vEvent.SetEventObject(this);
2101
2102 if (GetEventHandler()->ProcessEvent(vEvent))
2103 {
2104 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2105
2106 if (pBtn)
2107 {
2108 //
2109 // The button which has focus should be default
2110 //
2111 pBtn->SetDefault();
2112 }
2113 return TRUE;
2114 }
2115 }
2116 }
dae16775
DW
2117 //
2118 // Let Dialogs process
2119 //
2120 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
2121 return TRUE;
61243a51 2122 }
19193a2c
KB
2123#else
2124 pMsg = pMsg; // just shut up the compiler
2125#endif // __WXUNIVERSAL__
61243a51
DW
2126
2127#if wxUSE_TOOLTIPS
2128 if ( m_tooltip )
2129 {
2130 // relay mouse move events to the tooltip control
2131 QMSG* pQMsg = (QMSG*)pMsg;
2132
2133 if (pQMsg->msg == WM_MOUSEMOVE )
2134 m_tooltip->RelayEvent(pMsg);
2135 }
2136#endif // wxUSE_TOOLTIPS
2137
cdf1e714 2138 return FALSE;
0367c1c0 2139} // end of wxWindowOS2::OS2ProcessMessage
cdf1e714 2140
0367c1c0 2141bool wxWindowOS2::OS2TranslateMessage(
61243a51
DW
2142 WXMSG* pMsg
2143)
cdf1e714 2144{
19193a2c 2145#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
7e99520b
DW
2146 return m_acceleratorTable.Translate(m_hWnd, pMsg);
2147#else
19193a2c 2148 pMsg = pMsg;
7e99520b
DW
2149 return FALSE;
2150#endif //wxUSE_ACCEL
0367c1c0 2151} // end of wxWindowOS2::OS2TranslateMessage
cdf1e714
DW
2152
2153// ---------------------------------------------------------------------------
61243a51 2154// message params unpackers
cdf1e714
DW
2155// ---------------------------------------------------------------------------
2156
0367c1c0 2157void wxWindowOS2::UnpackCommand(
61243a51
DW
2158 WXWPARAM wParam
2159, WXLPARAM lParam
2160, WORD* pId
2161, WXHWND* phWnd
2162, WORD* pCmd
2163)
cdf1e714 2164{
5b3ed311
DW
2165 *pId = LOWORD(wParam);
2166 *phWnd = NULL; // or may be GetHWND() ?
2167 *pCmd = LOWORD(lParam);
0367c1c0 2168} // end of wxWindowOS2::UnpackCommand
cdf1e714 2169
0367c1c0 2170void wxWindowOS2::UnpackActivate(
61243a51
DW
2171 WXWPARAM wParam
2172, WXLPARAM lParam
2173, WXWORD* pState
2174, WXHWND* phWnd
2175)
cdf1e714 2176{
61243a51
DW
2177 *pState = LOWORD(wParam);
2178 *phWnd = (WXHWND)lParam;
0367c1c0 2179} // end of wxWindowOS2::UnpackActivate
cdf1e714 2180
0367c1c0 2181void wxWindowOS2::UnpackScroll(
61243a51
DW
2182 WXWPARAM wParam
2183, WXLPARAM lParam
2184, WXWORD* pCode
2185, WXWORD* pPos
2186, WXHWND* phWnd
2187)
cdf1e714 2188{
b7d8f285
DW
2189 ULONG ulId;
2190 HWND hWnd;
2191
2192 ulId = (ULONG)LONGFROMMP(wParam);
2193 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2194 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2195 *phWnd = NULLHANDLE;
2196 else
2197 *phWnd = hWnd;
2198
2199 *pPos = SHORT1FROMMP(lParam);
2200 *pCode = SHORT2FROMMP(lParam);
0367c1c0 2201} // end of wxWindowOS2::UnpackScroll
61243a51 2202
0367c1c0 2203void wxWindowOS2::UnpackMenuSelect(
61243a51
DW
2204 WXWPARAM wParam
2205, WXLPARAM lParam
2206, WXWORD* pItem
2207, WXWORD* pFlags
2208, WXHMENU* phMenu
2209)
cdf1e714 2210{
61243a51
DW
2211 *pItem = (WXWORD)LOWORD(wParam);
2212 *pFlags = HIWORD(wParam);
2213 *phMenu = (WXHMENU)lParam;
0367c1c0 2214} // end of wxWindowOS2::UnpackMenuSelect
cdf1e714
DW
2215
2216// ---------------------------------------------------------------------------
2217// Main wxWindows window proc and the window proc for wxWindow
2218// ---------------------------------------------------------------------------
2219
61243a51 2220//
cdf1e714
DW
2221// Hook for new window just as it's being created, when the window isn't yet
2222// associated with the handle
61243a51 2223//
19193a2c 2224wxWindowOS2* wxWndHook = NULL;
cdf1e714 2225
61243a51 2226//
cdf1e714 2227// Main window proc
61243a51 2228//
f23208ca 2229MRESULT EXPENTRY wxWndProc(
61243a51
DW
2230 HWND hWnd
2231, ULONG ulMsg
2232, MPARAM wParam
2233, MPARAM lParam
2234)
cdf1e714 2235{
61243a51
DW
2236 //
2237 // Trace all ulMsgs - useful for the debugging
2238 //
cdf1e714
DW
2239#ifdef __WXDEBUG__
2240 wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
61243a51 2241 wxGetMessageName(ulMsg), wParam, lParam);
cdf1e714
DW
2242#endif // __WXDEBUG__
2243
19193a2c 2244 wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
cdf1e714 2245
61243a51
DW
2246 //
2247 // When we get the first message for the HWND we just created, we associate
cdf1e714 2248 // it with wxWindow stored in wxWndHook
61243a51
DW
2249 //
2250 if (!pWnd && wxWndHook)
cdf1e714 2251 {
cdf1e714 2252 wxAssociateWinWithHandle(hWnd, wxWndHook);
61243a51 2253 pWnd = wxWndHook;
cdf1e714 2254 wxWndHook = NULL;
61243a51 2255 pWnd->SetHWND((WXHWND)hWnd);
cdf1e714
DW
2256 }
2257
5b3ed311 2258 MRESULT rc = (MRESULT)0;
e604d44b 2259
cdf1e714 2260
61243a51 2261 //
cdf1e714 2262 // Stop right here if we don't have a valid handle in our wxWindow object.
61243a51
DW
2263 //
2264 if (pWnd && !pWnd->GetHWND())
cdf1e714 2265 {
61243a51
DW
2266 pWnd->SetHWND((WXHWND) hWnd);
2267 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2268 pWnd->SetHWND(0);
cdf1e714
DW
2269 }
2270 else
2271 {
61243a51
DW
2272 if (pWnd)
2273 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
e604d44b 2274 else
61243a51 2275 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
cdf1e714 2276 }
5b3ed311 2277
cdf1e714 2278 return rc;
61243a51 2279} // end of wxWndProc
cdf1e714 2280
61243a51
DW
2281//
2282// We will add (or delete) messages we need to handle at this default
2283// level as we go
2284//
0367c1c0 2285MRESULT wxWindowOS2::OS2WindowProc(
61243a51
DW
2286 WXUINT uMsg
2287, WXWPARAM wParam
2288, WXLPARAM lParam
2289)
cdf1e714 2290{
61243a51
DW
2291 //
2292 // Did we process the uMsg?
2293 //
2294 bool bProcessed = FALSE;
e604d44b 2295 MRESULT mResult;
cdf1e714 2296
61243a51
DW
2297 //
2298 // For most messages we should return 0 when we do process the message
2299 //
e604d44b 2300 mResult = (MRESULT)0;
61243a51
DW
2301
2302 switch (uMsg)
cdf1e714
DW
2303 {
2304 case WM_CREATE:
2305 {
61243a51
DW
2306 bool bMayCreate;
2307
2308 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2309 ,&bMayCreate
2310 );
2311 if (bProcessed)
cdf1e714 2312 {
61243a51
DW
2313 //
2314 // Return 0 to bAllow window creation
2315 //
e604d44b 2316 mResult = (MRESULT)(bMayCreate ? 0 : -1);
cdf1e714
DW
2317 }
2318 }
2319 break;
2320
2321 case WM_DESTROY:
e604d44b
DW
2322 HandleDestroy();
2323 bProcessed = TRUE;
e604d44b 2324 break;
cdf1e714
DW
2325
2326 case WM_MOVE:
61243a51
DW
2327 bProcessed = HandleMove( LOWORD(lParam)
2328 ,HIWORD(lParam)
2329 );
cdf1e714
DW
2330 break;
2331
2332 case WM_SIZE:
61243a51
DW
2333 bProcessed = HandleSize( LOWORD(lParam)
2334 ,HIWORD(lParam)
2335 ,(WXUINT)wParam
2336 );
cdf1e714
DW
2337 break;
2338
2339 case WM_ACTIVATE:
2340 {
61243a51
DW
2341 WXWORD wState;
2342 WXHWND hWnd;
2343
2344 UnpackActivate( wParam
2345 ,lParam
2346 ,&wState
2347 ,&hWnd
2348 );
2349
2350 bProcessed = HandleActivate( wState
2351 ,(WXHWND)hWnd
2352 );
e604d44b 2353 bProcessed = FALSE;
cdf1e714
DW
2354 }
2355 break;
2356
2357 case WM_SETFOCUS:
61243a51
DW
2358 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2359 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2360 else
2361 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
cdf1e714
DW
2362 break;
2363
2364 case WM_PAINT:
61243a51 2365 bProcessed = HandlePaint();
cdf1e714
DW
2366 break;
2367
2368 case WM_CLOSE:
61243a51
DW
2369 //
2370 // Don't let the DefWindowProc() destroy our window - we'll do it
cdf1e714 2371 // ourselves in ~wxWindow
61243a51
DW
2372 //
2373 bProcessed = TRUE;
e604d44b 2374 mResult = (MRESULT)TRUE;
cdf1e714
DW
2375 break;
2376
61243a51
DW
2377 case WM_SHOW:
2378 bProcessed = HandleShow(wParam != 0, (int)lParam);
cdf1e714
DW
2379 break;
2380
61243a51
DW
2381 //
2382 // Under OS2 PM Joysticks are treated just like mouse events
2383 // The "Motion" events will be prevelent in joysticks
2384 //
cdf1e714 2385 case WM_MOUSEMOVE:
61243a51
DW
2386 case WM_BUTTON1DOWN:
2387 case WM_BUTTON1UP:
2388 case WM_BUTTON1DBLCLK:
2389 case WM_BUTTON1MOTIONEND:
2390 case WM_BUTTON1MOTIONSTART:
2391 case WM_BUTTON2DOWN:
2392 case WM_BUTTON2UP:
2393 case WM_BUTTON2DBLCLK:
2394 case WM_BUTTON2MOTIONEND:
2395 case WM_BUTTON2MOTIONSTART:
2396 case WM_BUTTON3DOWN:
2397 case WM_BUTTON3UP:
2398 case WM_BUTTON3DBLCLK:
2399 case WM_BUTTON3MOTIONEND:
2400 case WM_BUTTON3MOTIONSTART:
cdf1e714
DW
2401 {
2402 short x = LOWORD(lParam);
2403 short y = HIWORD(lParam);
2404
61243a51 2405 bProcessed = HandleMouseEvent(uMsg, x, y, (WXUINT)wParam);
cdf1e714
DW
2406 }
2407 break;
cdf1e714 2408 case WM_SYSCOMMAND:
61243a51 2409 bProcessed = HandleSysCommand(wParam, lParam);
cdf1e714
DW
2410 break;
2411
2412 case WM_COMMAND:
2413 {
2414 WORD id, cmd;
2415 WXHWND hwnd;
2416 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2417
61243a51 2418 bProcessed = HandleCommand(id, cmd, hwnd);
cdf1e714
DW
2419 }
2420 break;
2421
61243a51
DW
2422 //
2423 // For these messages we must return TRUE if process the message
2424 //
cdf1e714
DW
2425 case WM_DRAWITEM:
2426 case WM_MEASUREITEM:
2427 {
45bedfdd 2428 int nIdCtrl = (UINT)wParam;
45bedfdd 2429
61243a51 2430 if ( uMsg == WM_DRAWITEM )
cdf1e714 2431 {
45bedfdd 2432 bProcessed = OS2OnDrawItem(nIdCtrl,
cdf1e714
DW
2433 (WXDRAWITEMSTRUCT *)lParam);
2434 }
2435 else
2436 {
45bedfdd 2437 bProcessed = OS2OnMeasureItem(nIdCtrl,
cdf1e714
DW
2438 (WXMEASUREITEMSTRUCT *)lParam);
2439 }
2440
61243a51 2441 if ( bProcessed )
e604d44b 2442 mResult = (MRESULT)TRUE;
cdf1e714
DW
2443 }
2444 break;
2445
61243a51 2446 case WM_QUERYDLGCODE:
cdf1e714
DW
2447 if ( m_lDlgCode )
2448 {
e604d44b 2449 mResult = (MRESULT)m_lDlgCode;
61243a51 2450 bProcessed = TRUE;
cdf1e714 2451 }
61243a51 2452 //
cdf1e714 2453 //else: get the dlg code from the DefWindowProc()
61243a51 2454 //
cdf1e714
DW
2455 break;
2456
61243a51
DW
2457 //
2458 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2459 // and key-down events are obtained from the WM_CHAR params.
2460 //
2461 case WM_CHAR:
cdf1e714 2462 {
61243a51 2463 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 2464
61243a51
DW
2465 if (uKeyFlags & KC_KEYUP)
2466 {
19193a2c 2467 //TODO: check if the cast to WXWORD isn't causing trouble
987da0d4 2468 bProcessed = HandleKeyUp((WXDWORD)wParam, lParam);
cdf1e714 2469 break;
61243a51
DW
2470 }
2471 else // keydown event
2472 {
2473 //
2474 // If this has been processed by an event handler,
2475 // return 0 now (we've handled it). DON't RETURN
2476 // we still need to process further
2477 //
987da0d4 2478 HandleKeyDown((WXDWORD)wParam, lParam);
61243a51 2479 if (uKeyFlags & KC_VIRTUALKEY)
cdf1e714 2480 {
61243a51
DW
2481 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2482
2483 //
2484 // We consider these message "not interesting" to OnChar
2485 //
2486 if (uVk == VK_SHIFT || uVk == VK_CTRL )
2487 {
2488 bProcessed = TRUE;
2489 break;
2490 }
2491 switch(uVk)
2492 {
2493 //
2494 // Avoid duplicate messages to OnChar for these ASCII keys: they
2495 // will be translated by TranslateMessage() and received in WM_CHAR
2496 case VK_ESC:
2497 case VK_SPACE:
2498 case VK_ENTER:
2499 case VK_BACKSPACE:
2500 case VK_TAB:
2501 // But set processed to FALSE, not TRUE to still pass them to
2502 // the control's default window proc - otherwise built-in
2503 // keyboard handling won't work
2504 bProcessed = FALSE;
2505 break;
2506
2507 case VK_LEFT:
2508 case VK_RIGHT:
2509 case VK_DOWN:
2510 case VK_UP:
2511 default:
987da0d4 2512 bProcessed = HandleChar((WXDWORD)wParam, lParam);
61243a51
DW
2513 }
2514 break;
cdf1e714 2515 }
61243a51
DW
2516 else // WM_CHAR -- Always an ASCII character
2517 {
987da0d4 2518 bProcessed = HandleChar((WXDWORD)wParam, lParam, TRUE);
61243a51
DW
2519 break;
2520 }
2521 }
cdf1e714 2522 }
cdf1e714
DW
2523
2524 case WM_HSCROLL:
2525 case WM_VSCROLL:
2526 {
61243a51
DW
2527 WXWORD wCode;
2528 WXWORD wPos;
2529 WXHWND hWnd;
2530 UnpackScroll( wParam
2531 ,lParam
2532 ,&wCode
2533 ,&wPos
2534 ,&hWnd
2535 );
2536
2537 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2538 : wxVERTICAL
2539 ,wCode
2540 ,wPos
2541 ,hWnd
2542 );
cdf1e714
DW
2543 }
2544 break;
2545
61243a51
DW
2546#if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2547 case WM_CTLCOLORCHANGE:
cdf1e714 2548 {
e604d44b 2549 bProcessed = HandleCtlColor(&hBrush);
61243a51
DW
2550 }
2551 break;
2552#endif
8d854fa9
DW
2553 case WM_ERASEBACKGROUND:
2554 //
2555 // Returning TRUE to requestw PM to paint the window background
2556 // in SYSCLR_WINDOW. We don't really want that
2557 //
2558 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2559 mResult = (MRESULT)(FALSE);
2560 break;
2561
cdf1e714
DW
2562 // the return value for this message is ignored
2563 case WM_SYSCOLORCHANGE:
61243a51 2564 bProcessed = HandleSysColorChange();
cdf1e714
DW
2565 break;
2566
61243a51
DW
2567 case WM_REALIZEPALETTE:
2568 bProcessed = HandlePaletteChanged();
cdf1e714
DW
2569 break;
2570
61243a51
DW
2571 // move all drag and drops to wxDrg
2572 case WM_ENDDRAG:
2573 bProcessed = HandleEndDrag(wParam);
cdf1e714
DW
2574 break;
2575
61243a51
DW
2576 case WM_INITDLG:
2577 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
cdf1e714 2578
61243a51 2579 if ( bProcessed )
cdf1e714
DW
2580 {
2581 // we never set focus from here
e604d44b 2582 mResult = FALSE;
cdf1e714
DW
2583 }
2584 break;
2585
61243a51
DW
2586 // wxFrame specific message
2587 case WM_MINMAXFRAME:
f6bcfd97 2588 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
cdf1e714
DW
2589 break;
2590
61243a51
DW
2591 case WM_SYSVALUECHANGED:
2592 // TODO: do something
e604d44b 2593 mResult = (MRESULT)TRUE;
cdf1e714
DW
2594 break;
2595
61243a51
DW
2596 //
2597 // Comparable to WM_SETPOINTER for windows, only for just controls
2598 //
2599 case WM_CONTROLPOINTER:
2600 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2601 ,(HWND)lParam // Cursor Handle
2602 );
2603 if (bProcessed )
cdf1e714 2604 {
61243a51
DW
2605 //
2606 // Returning TRUE stops the DefWindowProc() from further
cdf1e714
DW
2607 // processing this message - exactly what we need because we've
2608 // just set the cursor.
61243a51 2609 //
e604d44b 2610 mResult = (MRESULT)TRUE;
cdf1e714
DW
2611 }
2612 break;
2613 }
61243a51 2614 if (!bProcessed)
cdf1e714
DW
2615 {
2616#ifdef __WXDEBUG__
2617 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
61243a51 2618 wxGetMessageName(uMsg));
cdf1e714 2619#endif // __WXDEBUG__
d08f23a7
DW
2620 if (IsKindOf(CLASSINFO(wxFrame)))
2621 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
2622 else
2623 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
cdf1e714 2624 }
e604d44b 2625 return mResult;
0367c1c0 2626} // end of wxWindowOS2::OS2WindowProc
cdf1e714 2627
61243a51 2628//
cdf1e714 2629// Dialog window proc
61243a51
DW
2630//
2631MRESULT wxDlgProc(
19193a2c 2632 HWND WXUNUSED(hWnd)
61243a51 2633, UINT uMsg
19193a2c
KB
2634, MPARAM WXUNUSED(wParam)
2635, MPARAM WXUNUSED(lParam))
cdf1e714 2636{
61243a51 2637 if (uMsg == WM_INITDLG)
cdf1e714 2638 {
61243a51
DW
2639 //
2640 // For this message, returning TRUE tells system to set focus to the
cdf1e714 2641 // first control in the dialog box
61243a51
DW
2642 //
2643 return (MRESULT)TRUE;
cdf1e714
DW
2644 }
2645 else
2646 {
61243a51
DW
2647 //
2648 // For all the other ones, FALSE means that we didn't process the
cdf1e714 2649 // message
61243a51
DW
2650 //
2651 return (MRESULT)0;
cdf1e714 2652 }
61243a51 2653} // end of wxDlgProc
cdf1e714 2654
61243a51
DW
2655wxWindow* wxFindWinFromHandle(
2656 WXHWND hWnd
2657)
cdf1e714 2658{
61243a51
DW
2659 wxNode* pNode = wxWinHandleList->Find((long)hWnd);
2660
2661 if (!pNode)
cdf1e714 2662 return NULL;
61243a51
DW
2663 return (wxWindow *)pNode->Data();
2664} // end of wxFindWinFromHandle
cdf1e714 2665
61243a51
DW
2666void wxAssociateWinWithHandle(
2667 HWND hWnd
19193a2c 2668, wxWindowOS2* pWin
61243a51 2669)
cdf1e714 2670{
61243a51
DW
2671 //
2672 // Adding NULL hWnd is (first) surely a result of an error and
cdf1e714 2673 // (secondly) breaks menu command processing
61243a51 2674 //
cdf1e714
DW
2675 wxCHECK_RET( hWnd != (HWND)NULL,
2676 wxT("attempt to add a NULL hWnd to window list ignored") );
2677
2678
61243a51
DW
2679 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
2680
2681 if (pOldWin && (pOldWin != pWin))
cdf1e714 2682 {
61243a51
DW
2683 wxString str(pWin->GetClassInfo()->GetClassName());
2684 wxLogError( "Bug! Found existing HWND %X for new window of class %s"
2685 ,(int)hWnd
2686 ,(const char*)str
2687 );
cdf1e714 2688 }
61243a51 2689 else if (!pOldWin)
cdf1e714 2690 {
61243a51
DW
2691 wxWinHandleList->Append( (long)hWnd
2692 ,pWin
2693 );
cdf1e714 2694 }
61243a51 2695} // end of wxAssociateWinWithHandle
cdf1e714 2696
61243a51 2697void wxRemoveHandleAssociation(
19193a2c 2698 wxWindowOS2* pWin
61243a51 2699)
cdf1e714 2700{
61243a51
DW
2701 wxWinHandleList->DeleteObject(pWin);
2702} // end of wxRemoveHandleAssociation
cdf1e714 2703
61243a51 2704//
cdf1e714
DW
2705// Default destroyer - override if you destroy it in some other way
2706// (e.g. with MDI child windows)
61243a51 2707//
0367c1c0 2708void wxWindowOS2::OS2DestroyWindow()
cdf1e714
DW
2709{
2710}
2711
0367c1c0 2712void wxWindowOS2::OS2DetachWindowMenu()
cdf1e714 2713{
19193a2c 2714#ifndef __WXUNIVERSAL__
61243a51 2715 if (m_hMenu)
cdf1e714 2716 {
61243a51 2717 HMENU hMenu = (HMENU)m_hMenu;
cdf1e714 2718
61243a51
DW
2719 int nN = (int)::WinSendMsg(hMenu, MM_QUERYITEMCOUNT, 0, 0);
2720 int i;
2721
2722 for (i = 0; i < nN; i++)
cdf1e714 2723 {
61243a51
DW
2724 wxChar zBuf[100];
2725 int nChars = (int)::WinSendMsg( hMenu
2726 ,MM_QUERYITEMTEXT
2727 ,MPFROM2SHORT(i, nN)
2728 ,zBuf
2729 );
2730 if (!nChars)
cdf1e714
DW
2731 {
2732 wxLogLastError(wxT("GetMenuString"));
cdf1e714
DW
2733 continue;
2734 }
2735
61243a51 2736 if (wxStrcmp(zBuf, wxT("&Window")) == 0)
cdf1e714 2737 {
61243a51 2738 ::WinSendMsg(hMenu, MM_DELETEITEM, MPFROM2SHORT(i, TRUE), 0);
cdf1e714
DW
2739 break;
2740 }
2741 }
2742 }
19193a2c 2743#endif // __WXUNIVERSAL__
0367c1c0 2744} // end of wxWindowOS2::OS2DetachWindowMenu
cdf1e714 2745
0367c1c0 2746bool wxWindowOS2::OS2Create(
f23208ca
DW
2747 WXHWND hParent
2748, PSZ zClass
61243a51 2749, const wxChar* zTitle
61243a51 2750, WXDWORD dwStyle
f23208ca
DW
2751, long lX
2752, long lY
2753, long lWidth
2754, long lHeight
2755, WXHWND hOwner
19193a2c 2756, WXHWND WXUNUSED(hZOrder)
f23208ca
DW
2757, unsigned long ulId
2758, void* pCtlData
2759, void* pPresParams
008089f6 2760, WXDWORD dwExStyle
61243a51
DW
2761)
2762{
914589c2
DW
2763 ERRORID vError;
2764 wxString sError;
5b3ed311 2765 long lX1 = 0L;
f23208ca 2766 long lY1 = 0L;
5b3ed311
DW
2767 long lWidth1 = 20L;
2768 long lHeight1 = 20L;
f23208ca 2769 int nControlId = 0;
51c1d535
DW
2770 int nNeedsubclass = 0;
2771 PCSZ pszClass = zClass;
cdf1e714 2772
61243a51 2773 //
cdf1e714
DW
2774 // Find parent's size, if it exists, to set up a possible default
2775 // panel size the size of the parent window
61243a51 2776 //
cb71578c
DW
2777 lX1 = lX;
2778 lY1 = lY;
f23208ca
DW
2779 if (lWidth > -1L)
2780 lWidth1 = lWidth;
2781 if (lHeight > -1L)
2782 lHeight1 = lHeight;
cdf1e714
DW
2783
2784 wxWndHook = this;
2785
f23208ca
DW
2786 //
2787 // check to see if the new window is a standard control
2788 //
2789 if ((ULONG)zClass == (ULONG)WC_BUTTON ||
2790 (ULONG)zClass == (ULONG)WC_COMBOBOX ||
2791 (ULONG)zClass == (ULONG)WC_CONTAINER ||
2792 (ULONG)zClass == (ULONG)WC_ENTRYFIELD ||
40bd6154 2793 (ULONG)zClass == (ULONG)WC_FRAME ||
f23208ca
DW
2794 (ULONG)zClass == (ULONG)WC_LISTBOX ||
2795 (ULONG)zClass == (ULONG)WC_MENU ||
2796 (ULONG)zClass == (ULONG)WC_NOTEBOOK ||
2797 (ULONG)zClass == (ULONG)WC_SCROLLBAR ||
2798 (ULONG)zClass == (ULONG)WC_SPINBUTTON ||
2799 (ULONG)zClass == (ULONG)WC_STATIC ||
2800 (ULONG)zClass == (ULONG)WC_TITLEBAR ||
2801 (ULONG)zClass == (ULONG)WC_VALUESET
2802 )
cdf1e714 2803 {
f23208ca 2804 nControlId = ulId;
cdf1e714 2805 }
51c1d535
DW
2806 else
2807 {
2808 // no standard controls
2809 if(wxString (wxT("wxFrameClass")) == wxString(zClass) )
2810 {
2811 pszClass = WC_FRAME;
2812 nNeedsubclass = 1;
2813 }
2814 else
2815 {
2816 nControlId = ulId;
2817 if(nControlId < 0)
2818 nControlId = FID_CLIENT;
2819 }
2820 }
cdf1e714 2821
19193a2c
KB
2822 HWND parent;
2823 if ( GetWindowStyleFlag() & wxPOPUP_WINDOW )
2824 {
2825 // popup windows should have desktop as parent because they shouldn't
2826 // be limited to the parents client area as child windows usually are
2827 parent = HWND_DESKTOP;
2828 }
2829 else if ( hParent )
2830 {
2831 parent = hParent;
2832 }
2833 else
2834 {
2835 // top level window
2836 parent = NULL;
2837 }
2838
f23208ca
DW
2839 //
2840 // We will either have a registered class via string name or a standard PM Class via a long
2841 //
19193a2c
KB
2842 m_hWnd = (WXHWND)::WinCreateWindow(parent, zClass,
2843 (PSZ)zTitle ? zTitle : wxT(""),
2844 dwStyle, lX1, lY1, lWidth, lHeight,
2845 hOwner, HWND_TOP, (ULONG)nControlId,
2846 pCtlData, pPresParams);
2847
f23208ca
DW
2848 if (!m_hWnd)
2849 {
2850 vError = ::WinGetLastError(vHabmain);
2851 sError = wxPMErrorToStr(vError);
2852 wxLogError("Can't create window of class %s!. Error: %s\n", zClass, sError);
2853 return FALSE;
cdf1e714 2854 }
008089f6 2855 m_dwExStyle = dwExStyle;
f6bcfd97 2856 ::WinSetWindowULong(m_hWnd, QWL_USER, (ULONG) this);
cdf1e714 2857 wxWndHook = NULL;
61243a51 2858
cdf1e714 2859#ifdef __WXDEBUG__
61243a51
DW
2860 wxNode* pNode = wxWinHandleList->Member(this);
2861
2862 if (pNode)
cdf1e714 2863 {
61243a51
DW
2864 HWND hWnd = (HWND)pNode->GetKeyInteger();
2865
2866 if (hWnd != (HWND)m_hWnd)
2867
cdf1e714
DW
2868 {
2869 wxLogError("A second HWND association is being added for the same window!");
2870 }
2871 }
2872#endif
61243a51
DW
2873 wxAssociateWinWithHandle((HWND)m_hWnd
2874 ,this
2875 );
cd212ee4 2876 //
e604d44b
DW
2877 // Now need to subclass window.
2878 //
51c1d535
DW
2879 if(!nNeedsubclass)
2880 {
2881 wxAssociateWinWithHandle((HWND)m_hWnd,this);
2882 }
2883 else
2884 {
2885 SubclassWin(GetHWND());
2886 }
cdf1e714 2887 return TRUE;
0367c1c0 2888} // end of wxWindowOS2::OS2Create
cdf1e714
DW
2889
2890// ===========================================================================
2891// OS2 PM message handlers
2892// ===========================================================================
2893
2894// ---------------------------------------------------------------------------
61243a51 2895// window creation/destruction
cdf1e714
DW
2896// ---------------------------------------------------------------------------
2897
0367c1c0 2898bool wxWindowOS2::HandleCreate(
19193a2c 2899 WXLPCREATESTRUCT WXUNUSED(vCs)
61243a51
DW
2900, bool* pbMayCreate
2901)
cdf1e714 2902{
19193a2c 2903 wxWindowCreateEvent vEvent((wxWindow*)this);
cdf1e714 2904
61243a51
DW
2905 (void)GetEventHandler()->ProcessEvent(vEvent);
2906 *pbMayCreate = TRUE;
cdf1e714 2907 return TRUE;
0367c1c0 2908} // end of wxWindowOS2::HandleCreate
cdf1e714 2909
0367c1c0 2910bool wxWindowOS2::HandleDestroy()
cdf1e714 2911{
19193a2c 2912 wxWindowDestroyEvent vEvent((wxWindow*)this);
cdf1e714 2913
61243a51
DW
2914 (void)GetEventHandler()->ProcessEvent(vEvent);
2915
2916 //
2917 // Delete our drop target if we've got one
2918 //
cdf1e714 2919#if wxUSE_DRAG_AND_DROP
61243a51 2920 if (m_dropTarget != NULL)
cdf1e714 2921 {
61243a51 2922 m_dropTarget->Revoke(m_hWnd);
cdf1e714
DW
2923 delete m_dropTarget;
2924 m_dropTarget = NULL;
2925 }
2926#endif // wxUSE_DRAG_AND_DROP
2927
61243a51 2928 //
cdf1e714 2929 // WM_DESTROY handled
61243a51 2930 //
cdf1e714 2931 return TRUE;
0367c1c0 2932} // end of wxWindowOS2::HandleDestroy
cdf1e714
DW
2933
2934// ---------------------------------------------------------------------------
2935// activation/focus
2936// ---------------------------------------------------------------------------
0367c1c0 2937void wxWindowOS2::OnSetFocus(
61243a51
DW
2938 wxFocusEvent& rEvent
2939)
cdf1e714 2940{
61243a51 2941 rEvent.Skip();
0367c1c0 2942} // end of wxWindowOS2::OnSetFocus
61243a51 2943
0367c1c0 2944bool wxWindowOS2::HandleActivate(
61243a51
DW
2945 int nState
2946, WXHWND WXUNUSED(hActivate)
2947)
2948{
2949 wxActivateEvent vEvent( wxEVT_ACTIVATE
2950 ,(bool)nState
2951 ,m_windowId
2952 );
2953 vEvent.SetEventObject(this);
2954 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2955} // end of wxWindowOS2::HandleActivate
61243a51 2956
0367c1c0 2957bool wxWindowOS2::HandleSetFocus(
61243a51
DW
2958 WXHWND WXUNUSED(hWnd)
2959)
cdf1e714
DW
2960{
2961#if wxUSE_CARET
61243a51 2962 //
cdf1e714 2963 // Deal with caret
61243a51
DW
2964 //
2965 if (m_caret)
cdf1e714
DW
2966 {
2967 m_caret->OnSetFocus();
2968 }
2969#endif // wxUSE_CARET
2970
1bcfc0e1
DW
2971#if wxUSE_TEXTCTRL
2972 // If it's a wxTextCtrl don't send the event as it will be done
2973 // after the control gets to process it from EN_FOCUS handler
2974 if ( wxDynamicCastThis(wxTextCtrl) )
cdf1e714 2975 {
1bcfc0e1 2976 return FALSE;
cdf1e714 2977 }
1bcfc0e1 2978#endif // wxUSE_TEXTCTRL
cdf1e714 2979
61243a51 2980 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
cdf1e714 2981
61243a51
DW
2982 vEvent.SetEventObject(this);
2983 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2984} // end of wxWindowOS2::HandleSetFocus
cdf1e714 2985
0367c1c0 2986bool wxWindowOS2::HandleKillFocus(
61243a51
DW
2987 WXHWND WXUNUSED(hWnd)
2988)
cdf1e714
DW
2989{
2990#if wxUSE_CARET
61243a51 2991 //
cdf1e714 2992 // Deal with caret
61243a51
DW
2993 //
2994 if (m_caret)
cdf1e714
DW
2995 {
2996 m_caret->OnKillFocus();
2997 }
2998#endif // wxUSE_CARET
2999
61243a51
DW
3000 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
3001 ,m_windowId
3002 );
cdf1e714 3003
61243a51
DW
3004 vEvent.SetEventObject(this);
3005 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3006} // end of wxWindowOS2::HandleKillFocus
cdf1e714
DW
3007
3008// ---------------------------------------------------------------------------
3009// miscellaneous
3010// ---------------------------------------------------------------------------
3011
0367c1c0 3012bool wxWindowOS2::HandleShow(
61243a51 3013 bool bShow
19193a2c 3014, int WXUNUSED(nStatus)
61243a51 3015)
cdf1e714 3016{
19193a2c 3017 wxShowEvent vEvent(GetId(), bShow);
cdf1e714 3018
61243a51
DW
3019 vEvent.m_eventObject = this;
3020 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3021} // end of wxWindowOS2::HandleShow
cdf1e714 3022
0367c1c0 3023bool wxWindowOS2::HandleInitDialog(
61243a51
DW
3024 WXHWND WXUNUSED(hWndFocus)
3025)
cdf1e714 3026{
61243a51 3027 wxInitDialogEvent vEvent(GetId());
cdf1e714 3028
61243a51
DW
3029 vEvent.m_eventObject = this;
3030 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3031} // end of wxWindowOS2::HandleInitDialog
cdf1e714 3032
19193a2c 3033bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
cdf1e714 3034{
61243a51 3035 // TODO: We'll handle drag and drop later
cdf1e714
DW
3036 return FALSE;
3037}
3038
0367c1c0 3039bool wxWindowOS2::HandleSetCursor(
19193a2c 3040 USHORT WXUNUSED(vId)
61243a51
DW
3041, WXHWND hPointer
3042)
cdf1e714 3043{
61243a51
DW
3044 //
3045 // Under OS/2 PM this allows the pointer to be changed
3046 // as it passes over a control
3047 //
3048 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
3049 return TRUE;
0367c1c0 3050} // end of wxWindowOS2::HandleSetCursor
cdf1e714
DW
3051
3052// ---------------------------------------------------------------------------
3053// owner drawn stuff
3054// ---------------------------------------------------------------------------
0367c1c0 3055bool wxWindowOS2::OS2OnDrawItem(
61243a51
DW
3056 int vId
3057, WXDRAWITEMSTRUCT* pItemStruct
3058)
cdf1e714 3059{
19193a2c 3060#if wxUSE_OWNER_DRAWN
402e2f7c 3061 wxDC vDc;
61243a51 3062
19193a2c 3063#if wxUSE_MENUS_NATIVE
61243a51 3064 //
402e2f7c 3065 // Is it a menu item?
61243a51 3066 //
402e2f7c
DW
3067 if (vId == 0)
3068 {
5afb9458
DW
3069 ERRORID vError;
3070 wxString sError;
402e2f7c 3071 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
23122f8c
DW
3072 wxFrame* pFrame = (wxFrame*)this;
3073 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
402e2f7c 3074 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
23122f8c
DW
3075 wxRect vRect( pMeasureStruct->rclItem.xLeft
3076 ,pMeasureStruct->rclItem.yBottom
3077 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3078 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3079 );
402e2f7c
DW
3080 vDc.SetHDC( hDC
3081 ,FALSE
3082 );
3083 vDc.SetHPS(pMeasureStruct->hps);
5afb9458
DW
3084 //
3085 // Load the wxWindows Pallete and set to RGB mode
3086 //
3087 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3088 ,0L
3089 ,LCOLF_CONSECRGB
3090 ,0L
3091 ,(LONG)wxTheColourDatabase->m_nSize
3092 ,(PLONG)wxTheColourDatabase->m_palTable
3093 ))
3094 {
3095 vError = ::WinGetLastError(vHabmain);
3096 sError = wxPMErrorToStr(vError);
3097 wxLogError("Unable to set current color table. Error: %s\n", sError);
3098 }
3099 //
3100 // Set the color table to RGB mode
3101 //
3102 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3103 ,0L
3104 ,LCOLF_RGB
3105 ,0L
3106 ,0L
3107 ,NULL
3108 ))
3109 {
3110 vError = ::WinGetLastError(vHabmain);
3111 sError = wxPMErrorToStr(vError);
3112 wxLogError("Unable to set current color table. Error: %s\n", sError);
3113 }
cdf1e714 3114
23122f8c
DW
3115 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3116
3117
3118 int eAction = 0;
3119 int eStatus = 0;
cdf1e714 3120
402e2f7c 3121 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
23122f8c
DW
3122 {
3123 //
3124 // Entire Item needs to be redrawn (either it has reappeared from
3125 // behind another window or is being displayed for the first time
3126 //
402e2f7c 3127 eAction = wxOwnerDrawn::wxODDrawAll;
23122f8c
DW
3128
3129 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3130 {
3131 //
3132 // If it is currently selected we let the system handle it
3133 //
3134 eStatus |= wxOwnerDrawn::wxODSelected;
3135 }
3136 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3137 {
3138 //
3139 // If it is currently checked we draw our own
3140 //
3141 eStatus |= wxOwnerDrawn::wxODChecked;
3142 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3143 }
3144 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3145 {
3146 //
3147 // If it is currently disabled we let the system handle it
3148 //
3149 eStatus |= wxOwnerDrawn::wxODDisabled;
3150 }
3151 //
3152 // Don't really care about framed (indicationg focus) or NoDismiss
3153 //
3154 }
402e2f7c 3155 else
23122f8c 3156 {
5afb9458
DW
3157 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3158 {
3159 eAction = wxOwnerDrawn::wxODDrawAll;
3160 eStatus |= wxOwnerDrawn::wxODSelected;
3161 //
3162 // Keep the system from trying to highlight with its bogus colors
3163 //
3164 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3165 }
3166 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3167 {
3168 eAction = wxOwnerDrawn::wxODDrawAll;
3169 eStatus = 0;
3170 //
3171 // Keep the system from trying to highlight with its bogus colors
3172 //
3173 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3174 }
3175 else
3176 {
3177 //
3178 // For now we don't care about anything else
3179 // just ignore the entire message!
3180 //
3181 return TRUE;
3182 }
23122f8c
DW
3183 }
3184 //
3185 // Now redraw the item
3186 //
45bedfdd
DW
3187 return(pMenuItem->OnDrawItem( vDc
3188 ,vRect
23122f8c
DW
3189 ,(wxOwnerDrawn::wxODAction)eAction
3190 ,(wxOwnerDrawn::wxODStatus)eStatus
45bedfdd 3191 ));
402e2f7c
DW
3192 //
3193 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3194 // the system will do the highlight or fraeming or disabling for us,
3195 // otherwise, we'd have to do it ourselves.
61243a51 3196 //
cdf1e714 3197 }
19193a2c 3198#endif // wxUSE_MENUS_NATIVE
cdf1e714 3199
402e2f7c
DW
3200 wxWindow* pItem = FindItem(vId);
3201
3202 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3203 {
3204 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3205 }
19193a2c
KB
3206#else
3207 vId = vId;
3208 pItemStruct = pItemStruct;
61243a51 3209#endif
402e2f7c 3210 return FALSE;
0367c1c0 3211} // end of wxWindowOS2::OS2OnDrawItem
cdf1e714 3212
0367c1c0 3213bool wxWindowOS2::OS2OnMeasureItem(
402e2f7c
DW
3214 int lId
3215, WXMEASUREITEMSTRUCT* pItemStruct
3216)
0e320a79 3217{
19193a2c 3218#if wxUSE_OWNER_DRAWN
402e2f7c
DW
3219 //
3220 // Is it a menu item?
3221 //
45bedfdd 3222 if (lId == 65536) // I really don't like this...has to be a better indicator
cdf1e714 3223 {
4049cc1c 3224 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
45bedfdd 3225 {
4049cc1c
DW
3226 size_t nWidth;
3227 size_t nHeight;
3228 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
45bedfdd
DW
3229 wxFrame* pFrame = (wxFrame*)this;
3230 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
cdf1e714 3231
45bedfdd 3232 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
4049cc1c
DW
3233 nWidth = 0L;
3234 nHeight = 0L;
3235 if (pMenuItem->OnMeasureItem( &nWidth
3236 ,&nHeight
3237 ))
3238 {
3239 pMeasureStruct->rclItem.xRight = nWidth;
3240 pMeasureStruct->rclItem.xLeft = 0L;
3241 pMeasureStruct->rclItem.yTop = nHeight;
3242 pMeasureStruct->rclItem.yBottom = 0L;
3243 return TRUE;
3244 }
3245 return FALSE;
45bedfdd 3246 }
cdf1e714 3247 }
f15b4952 3248 wxWindow* pItem = FindItem(lId);
cdf1e714 3249
402e2f7c 3250 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
cdf1e714 3251 {
402e2f7c 3252 return ((wxControl *)pItem)->OS2OnMeasure(pItemStruct);
cdf1e714 3253 }
19193a2c
KB
3254#else
3255 lId = lId;
3256 pItemStruct = pItemStruct;
3257#endif // wxUSE_OWNER_DRAWN
cdf1e714 3258 return FALSE;
0e320a79
DW
3259}
3260
cdf1e714
DW
3261// ---------------------------------------------------------------------------
3262// colours and palettes
3263// ---------------------------------------------------------------------------
849949b1 3264
0367c1c0 3265bool wxWindowOS2::HandleSysColorChange()
0e320a79 3266{
61243a51 3267 wxSysColourChangedEvent vEvent;
cdf1e714 3268
61243a51
DW
3269 vEvent.SetEventObject(this);
3270 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3271} // end of wxWindowOS2::HandleSysColorChange
0e320a79 3272
0367c1c0 3273bool wxWindowOS2::HandleCtlColor(
19193a2c 3274 WXHBRUSH* WXUNUSED(phBrush)
61243a51 3275)
0e320a79 3276{
61243a51
DW
3277 //
3278 // Not much provided with message. So not sure I can do anything with it
3279 //
3280 return TRUE;
0367c1c0 3281} // end of wxWindowOS2::HandleCtlColor
cdf1e714 3282
0e320a79 3283
cdf1e714 3284// Define for each class of dialog and control
19193a2c
KB
3285WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
3286 WXHWND WXUNUSED(hWnd),
3287 WXUINT WXUNUSED(nCtlColor),
3288 WXUINT WXUNUSED(message),
3289 WXWPARAM WXUNUSED(wParam),
3290 WXLPARAM WXUNUSED(lParam))
0e320a79 3291{
cdf1e714 3292 return (WXHBRUSH)0;
0e320a79
DW
3293}
3294
0367c1c0 3295bool wxWindowOS2::HandlePaletteChanged()
0e320a79 3296{
61243a51
DW
3297 // need to set this to something first
3298 WXHWND hWndPalChange = NULLHANDLE;
cdf1e714 3299
61243a51
DW
3300 wxPaletteChangedEvent vEvent(GetId());
3301
3302 vEvent.SetEventObject(this);
3303 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
0e320a79 3304
61243a51 3305 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3306} // end of wxWindowOS2::HandlePaletteChanged
61243a51 3307
61243a51 3308//
cdf1e714 3309// Responds to colour changes: passes event on to children.
61243a51 3310//
0367c1c0 3311void wxWindowOS2::OnSysColourChanged(
61243a51
DW
3312 wxSysColourChangedEvent& rEvent
3313)
0e320a79 3314{
61243a51
DW
3315 wxNode* pNode = GetChildren().First();
3316
3317 while (pNode)
cdf1e714 3318 {
61243a51 3319 //
cdf1e714 3320 // Only propagate to non-top-level windows
61243a51
DW
3321 //
3322 wxWindow* pWin = (wxWindow *)pNode->Data();
3323
3324 if (pWin->GetParent())
cdf1e714 3325 {
61243a51 3326 wxSysColourChangedEvent vEvent;
cdf1e714 3327
61243a51
DW
3328 rEvent.m_eventObject = pWin;
3329 pWin->GetEventHandler()->ProcessEvent(vEvent);
3330 }
3331 pNode = pNode->Next();
cdf1e714 3332 }
0367c1c0 3333} // end of wxWindowOS2::OnSysColourChanged
0e320a79 3334
cdf1e714
DW
3335// ---------------------------------------------------------------------------
3336// painting
3337// ---------------------------------------------------------------------------
3338
0367c1c0 3339bool wxWindowOS2::HandlePaint()
0e320a79 3340{
19193a2c
KB
3341 HRGN hRgn;
3342 wxPaintEvent vEvent(m_windowId);
40bd6154
DW
3343 HPS hPS;
3344 RECTL vRect;
19193a2c
KB
3345 bool bProcessed;
3346
3347 // Create empty region
3348 // TODO: get HPS somewhere else if possible
3349 hPS = ::WinGetPS(GetHwnd());
3350 hRgn = ::GpiCreateRegion(hPS, 0, NULL);
61243a51 3351
19193a2c 3352 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
61243a51
DW
3353 {
3354 wxLogLastError("CreateRectRgn");
3355 return FALSE;
3356 }
7e99520b 3357
19193a2c
KB
3358 m_updateRegion = wxRegion(hRgn, hPS);
3359
61243a51 3360 vEvent.SetEventObject(this);
19193a2c
KB
3361 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
3362
19193a2c 3363 return GetEventHandler()->ProcessEvent(vEvent); //bProcessed;
0367c1c0 3364} // end of wxWindowOS2::HandlePaint
0e320a79 3365
0367c1c0 3366bool wxWindowOS2::HandleEraseBkgnd(
8d854fa9
DW
3367 WXHDC hDC
3368)
0e320a79 3369{
8d854fa9 3370 SWP vSwp;
19193a2c 3371 bool rc;
8d854fa9
DW
3372
3373 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3374 if (vSwp.fl & SWP_MINIMIZE)
61243a51 3375 return TRUE;
cdf1e714 3376
8d854fa9
DW
3377 wxDC vDC;
3378
3379 vDC.m_hPS = (HPS)hDC; // this is really a PS
19193a2c 3380 vDC.SetWindow((wxWindow*)this);
8d854fa9 3381 vDC.BeginDrawing();
cdf1e714 3382
8d854fa9
DW
3383 wxEraseEvent vEvent(m_windowId, &vDC);
3384
3385 vEvent.SetEventObject(this);
cdf1e714 3386
19193a2c 3387 rc = GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3388
8d854fa9
DW
3389 vDC.EndDrawing();
3390 vDC.m_hPS = NULLHANDLE;
61243a51 3391 return TRUE;
0367c1c0 3392} // end of wxWindowOS2::HandleEraseBkgnd
cdf1e714 3393
0367c1c0 3394void wxWindowOS2::OnEraseBackground(
61243a51
DW
3395 wxEraseEvent& rEvent
3396)
0e320a79 3397{
8d854fa9
DW
3398 RECTL vRect;
3399 HPS hPS = rEvent.m_dc->m_hPS;
19193a2c
KB
3400 APIRET rc;
3401 LONG lColor = m_backgroundColour.GetPixel();
8d854fa9 3402
19193a2c
KB
3403 rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
3404 rc = ::WinFillRect(hPS, &vRect, lColor);
0367c1c0 3405} // end of wxWindowOS2::OnEraseBackground
0e320a79 3406
cdf1e714
DW
3407// ---------------------------------------------------------------------------
3408// moving and resizing
3409// ---------------------------------------------------------------------------
0e320a79 3410
0367c1c0 3411bool wxWindowOS2::HandleMinimize()
0e320a79 3412{
61243a51 3413 wxIconizeEvent vEvent(m_windowId);
cdf1e714 3414
61243a51
DW
3415 vEvent.SetEventObject(this);
3416 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3417} // end of wxWindowOS2::HandleMinimize
0e320a79 3418
0367c1c0 3419bool wxWindowOS2::HandleMaximize()
0e320a79 3420{
61243a51 3421 wxMaximizeEvent vEvent(m_windowId);
cdf1e714 3422
61243a51
DW
3423 vEvent.SetEventObject(this);
3424 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3425} // end of wxWindowOS2::HandleMaximize
0e320a79 3426
0367c1c0 3427bool wxWindowOS2::HandleMove(
61243a51
DW
3428 int nX
3429, int nY
3430)
0e320a79 3431{
19193a2c 3432 wxMoveEvent vEvent(wxPoint(nX, nY), m_windowId);
cdf1e714 3433
61243a51
DW
3434 vEvent.SetEventObject(this);
3435 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3436} // end of wxWindowOS2::HandleMove
0e320a79 3437
0367c1c0 3438bool wxWindowOS2::HandleSize(
61243a51
DW
3439 int nWidth
3440, int nHeight
3441, WXUINT WXUNUSED(nFlag)
3442)
0e320a79 3443{
19193a2c 3444 wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
cdf1e714 3445
61243a51
DW
3446 vEvent.SetEventObject(this);
3447 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3448} // end of wxWindowOS2::HandleSize
0e320a79 3449
0367c1c0 3450bool wxWindowOS2::HandleGetMinMaxInfo(
61243a51
DW
3451 PSWP pSwp
3452)
0e320a79 3453{
61243a51
DW
3454 bool bRc = FALSE;
3455 POINTL vPoint;
cdf1e714 3456
61243a51 3457 switch(pSwp->fl)
cdf1e714 3458 {
61243a51
DW
3459 case SWP_MAXIMIZE:
3460 ::WinGetMaxPosition(GetHwnd(), pSwp);
3461 m_maxWidth = pSwp->cx;
3462 m_maxHeight = pSwp->cy;
3463 break;
cdf1e714 3464
61243a51
DW
3465 case SWP_MINIMIZE:
3466 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3467 m_minWidth = pSwp->cx;
3468 m_minHeight = pSwp->cy;
3469 break;
cdf1e714 3470
61243a51
DW
3471 default:
3472 return FALSE;
cdf1e714 3473 }
61243a51 3474 return TRUE;
0367c1c0 3475} // end of wxWindowOS2::HandleGetMinMaxInfo
0e320a79 3476
cdf1e714
DW
3477// ---------------------------------------------------------------------------
3478// command messages
3479// ---------------------------------------------------------------------------
0367c1c0 3480bool wxWindowOS2::HandleCommand(
61243a51
DW
3481 WXWORD wId
3482, WXWORD wCmd
3483, WXHWND hControl
3484)
0e320a79 3485{
19193a2c 3486#if wxUSE_MENUS_NATIVE
61243a51 3487 if (wxCurrentPopupMenu)
0e320a79 3488 {
61243a51 3489 wxMenu* pPopupMenu = wxCurrentPopupMenu;
0e320a79 3490
61243a51
DW
3491 wxCurrentPopupMenu = NULL;
3492 return pPopupMenu->OS2Command(wCmd, wId);
cdf1e714 3493 }
19193a2c 3494#endif // wxUSE_MENUS_NATIVE
0e320a79 3495
61243a51
DW
3496 wxWindow* pWin = FindItem(wId);
3497
3498 if (!pWin)
cdf1e714 3499 {
61243a51 3500 pWin = wxFindWinFromHandle(hControl);
0e320a79 3501 }
cdf1e714 3502
61243a51 3503 if (pWin)
19193a2c
KB
3504 return pWin->OS2Command(wCmd, wId);
3505
cdf1e714 3506 return FALSE;
0367c1c0 3507} // end of wxWindowOS2::HandleCommand
de44a9f0 3508
0367c1c0 3509bool wxWindowOS2::HandleSysCommand(
61243a51 3510 WXWPARAM wParam
19193a2c 3511, WXLPARAM WXUNUSED(lParam)
61243a51 3512)
0e320a79 3513{
61243a51
DW
3514 //
3515 // 4 bits are reserved
3516 //
3517 switch (SHORT1FROMMP(wParam))
3518 {
3519 case SC_MAXIMIZE:
3520 return HandleMaximize();
3521
3522 case SC_MINIMIZE:
3523 return HandleMinimize();
3524 }
cdf1e714 3525 return FALSE;
0367c1c0 3526} // end of wxWindowOS2::HandleSysCommand
cdf1e714
DW
3527
3528// ---------------------------------------------------------------------------
3529// mouse events
3530// ---------------------------------------------------------------------------
19193a2c 3531//TODO!!! check against MSW
0367c1c0 3532void wxWindowOS2::InitMouseEvent(
61243a51
DW
3533 wxMouseEvent& rEvent
3534, int nX
3535, int nY
3536, WXUINT uFlags
3537)
cdf1e714 3538{
61243a51
DW
3539 rEvent.m_x = nX;
3540 rEvent.m_y = nY;
3541 rEvent.m_shiftDown = ((uFlags & VK_SHIFT) != 0);
3542 rEvent.m_controlDown = ((uFlags & VK_CTRL) != 0);
3543 rEvent.m_leftDown = ((uFlags & VK_BUTTON1) != 0);
3544 rEvent.m_middleDown = ((uFlags & VK_BUTTON3) != 0);
3545 rEvent.m_rightDown = ((uFlags & VK_BUTTON2) != 0);
3546 rEvent.SetTimestamp(s_currentMsg.time);
3547 rEvent.m_eventObject = this;
cdf1e714
DW
3548
3549#if wxUSE_MOUSEEVENT_HACK
61243a51
DW
3550 m_lastMouseX = nX;
3551 m_lastMouseY = nY;
3552 m_lastMouseEvent = rEvent.GetEventType();
cdf1e714 3553#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 3554} // end of wxWindowOS2::InitMouseEvent
0e320a79 3555
0367c1c0 3556bool wxWindowOS2::HandleMouseEvent(
61243a51
DW
3557 WXUINT uMsg
3558, int nX
3559, int nY
3560, WXUINT uFlags
3561)
0e320a79 3562{
61243a51
DW
3563 //
3564 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
cdf1e714
DW
3565 // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
3566 // from the message id and take the value in the table to get wxWin event
3567 // id
61243a51 3568 //
cdf1e714
DW
3569 static const wxEventType eventsMouse[] =
3570 {
3571 wxEVT_MOTION,
3572 wxEVT_LEFT_DOWN,
3573 wxEVT_LEFT_UP,
3574 wxEVT_LEFT_DCLICK,
3575 wxEVT_RIGHT_DOWN,
3576 wxEVT_RIGHT_UP,
3577 wxEVT_RIGHT_DCLICK,
3578 wxEVT_MIDDLE_DOWN,
3579 wxEVT_MIDDLE_UP,
3580 wxEVT_MIDDLE_DCLICK
3581 };
3582
61243a51 3583 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
cdf1e714 3584
61243a51
DW
3585 InitMouseEvent( vEvent
3586 ,nX
3587 ,nY
3588 ,uFlags
3589 );
0e320a79 3590
61243a51 3591 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3592} // end of wxWindowOS2::HandleMouseEvent
61243a51 3593
0367c1c0 3594bool wxWindowOS2::HandleMouseMove(
61243a51
DW
3595 int nX
3596, int nY
3597, WXUINT uFlags
3598)
0e320a79 3599{
61243a51 3600 if (!m_bMouseInWindow)
cdf1e714 3601 {
61243a51 3602 //
cdf1e714 3603 // Generate an ENTER event
61243a51 3604 //
776d87d5 3605 m_bMouseInWindow = TRUE;
cdf1e714 3606
61243a51 3607 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
cdf1e714 3608
61243a51
DW
3609 InitMouseEvent( vEvent
3610 ,nX
3611 ,nY
3612 ,uFlags
3613 );
cdf1e714 3614
61243a51 3615 (void)GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3616 }
61243a51
DW
3617 return HandleMouseEvent( WM_MOUSEMOVE
3618 ,nX
3619 ,nY
3620 ,uFlags
3621 );
0367c1c0 3622} // end of wxWindowOS2::HandleMouseMove
0e320a79 3623
cdf1e714
DW
3624// ---------------------------------------------------------------------------
3625// keyboard handling
3626// ---------------------------------------------------------------------------
3627
61243a51
DW
3628//
3629// Create the key event of the given type for the given key - used by
3630// HandleChar and HandleKeyDown/Up
3631//
0367c1c0 3632wxKeyEvent wxWindowOS2::CreateKeyEvent(
61243a51
DW
3633 wxEventType eType
3634, int nId
3635, WXLPARAM lParam
3636) const
3637{
3638 wxKeyEvent vEvent(eType);
3639
3640 vEvent.SetId(GetId());
3641 vEvent.m_shiftDown = IsShiftDown();
3642 vEvent.m_controlDown = IsCtrlDown();
3643 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
3644
3645 vEvent.m_eventObject = (wxWindow *)this; // const_cast
3646 vEvent.m_keyCode = nId;
3647 vEvent.SetTimestamp(s_currentMsg.time);
3648
3649 //
3650 // Translate the position to client coords
3651 //
3652 POINTL vPoint;
3653 RECTL vRect;
3654
3655 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
3656 ::WinQueryWindowRect( GetHwnd()
3657 ,&vRect
3658 );
3659
3660 vPoint.x -= vRect.xLeft;
3661 vPoint.y -= vRect.yBottom;
3662
3663 vEvent.m_x = vPoint.x;
3664 vEvent.m_y = vPoint.y;
3665
3666 return vEvent;
0367c1c0 3667} // end of wxWindowOS2::CreateKeyEvent
61243a51
DW
3668
3669//
cdf1e714
DW
3670// isASCII is TRUE only when we're called from WM_CHAR handler and not from
3671// WM_KEYDOWN one
61243a51 3672//
0367c1c0 3673bool wxWindowOS2::HandleChar(
987da0d4 3674 WXDWORD wParam
61243a51
DW
3675, WXLPARAM lParam
3676, bool isASCII
3677)
86de7616 3678{
61243a51
DW
3679 bool bCtrlDown = FALSE;
3680 int vId;
3681
3682 if (isASCII)
3683 {
3684 //
3685 // If 1 -> 26, translate to CTRL plus a letter.
3686 //
3687 vId = wParam;
3688 if ((vId > 0) && (vId < 27))
3689 {
3690 switch (vId)
3691 {
3692 case 13:
3693 vId = WXK_RETURN;
3694 break;
3695
3696 case 8:
3697 vId = WXK_BACK;
3698 break;
3699
3700 case 9:
3701 vId = WXK_TAB;
3702 break;
3703
3704 default:
3705 bCtrlDown = TRUE;
3706 vId = vId + 96;
3707 }
3708 }
3709 }
3710 else if ( (vId = wxCharCodeOS2ToWX(wParam)) == 0)
3711 {
3712 //
3713 // It's ASCII and will be processed here only when called from
3714 // WM_CHAR (i.e. when isASCII = TRUE), don't process it now
3715 //
3716 vId = -1;
3717 }
3718
3719 if (vId != -1)
3720 {
3721 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
3722 ,vId
3723 ,lParam
3724 ));
3725
3726 if (bCtrlDown)
3727 {
3728 vEvent.m_controlDown = TRUE;
3729 }
3730
3731 if (GetEventHandler()->ProcessEvent(vEvent))
3732 return TRUE;
3733 }
3734 return FALSE;
cdf1e714 3735}
86de7616 3736
0367c1c0 3737bool wxWindowOS2::HandleKeyDown(
61243a51
DW
3738 WXWORD wParam
3739, WXLPARAM lParam
3740)
cdf1e714 3741{
61243a51 3742 int nId = wxCharCodeOS2ToWX(wParam);
86de7616 3743
61243a51
DW
3744 if (!nId)
3745 {
3746 //
3747 // Normal ASCII char
3748 //
3749 nId = wParam;
3750 }
3751
3752 if (nId != -1)
3753 {
3754 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
3755 ,nId
3756 ,lParam
3757 ));
3758
3759 if (GetEventHandler()->ProcessEvent(vEvent))
3760 {
3761 return TRUE;
3762 }
3763 }
3764 return FALSE;
0367c1c0 3765} // end of wxWindowOS2::HandleKeyDown
61243a51 3766
0367c1c0 3767bool wxWindowOS2::HandleKeyUp(
987da0d4 3768 WXDWORD wParam
61243a51
DW
3769, WXLPARAM lParam
3770)
86de7616 3771{
61243a51
DW
3772 int nId = wxCharCodeOS2ToWX(wParam);
3773
3774 if (!nId)
3775 {
3776 //
3777 // Normal ASCII char
3778 //
3779 nId = wParam;
3780 }
3781
3782 if (nId != -1)
3783 {
3784 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
3785 ,nId
3786 ,lParam
3787 ));
3788
3789 if (GetEventHandler()->ProcessEvent(vEvent))
3790 return TRUE;
3791 }
3792 return FALSE;
0367c1c0 3793} // end of wxWindowOS2::HandleKeyUp
86de7616 3794
cdf1e714
DW
3795// ---------------------------------------------------------------------------
3796// joystick
3797// ---------------------------------------------------------------------------
86de7616 3798
cdf1e714
DW
3799// ---------------------------------------------------------------------------
3800// scrolling
3801// ---------------------------------------------------------------------------
3802
0367c1c0 3803bool wxWindowOS2::OS2OnScroll(
61243a51
DW
3804 int nOrientation
3805, WXWORD wParam
3806, WXWORD wPos
3807, WXHWND hControl
3808)
cdf1e714 3809{
61243a51 3810 if (hControl)
86de7616 3811 {
61243a51
DW
3812 wxWindow* pChild = wxFindWinFromHandle(hControl);
3813
3814 if (pChild )
3815 return pChild->OS2OnScroll( nOrientation
3816 ,wParam
3817 ,wPos
3818 ,hControl
3819 );
cdf1e714 3820 }
86de7616 3821
61243a51
DW
3822 wxScrollWinEvent vEvent;
3823
3824 vEvent.SetPosition(wPos);
3825 vEvent.SetOrientation(nOrientation);
3826 vEvent.m_eventObject = this;
3827
3828 switch (wParam)
3829 {
3830 case SB_LINEUP:
3831 vEvent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
3832 break;
3833
3834 case SB_LINEDOWN:
3835 vEvent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
3836 break;
3837
3838 case SB_PAGEUP:
3839 vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
3840 break;
3841
3842 case SB_PAGEDOWN:
3843 vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
3844 break;
3845
3846 case SB_SLIDERPOSITION:
3847 vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
3848 break;
3849
3850 case SB_SLIDERTRACK:
3851 vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
3852 break;
3853
3854 default:
3855 return FALSE;
3856 }
3857 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3858} // end of wxWindowOS2::OS2OnScroll
86de7616 3859
cdf1e714
DW
3860// ===========================================================================
3861// global functions
3862// ===========================================================================
3863
61243a51 3864void wxGetCharSize(
987da0d4
DW
3865 WXHWND hWnd
3866, int* pX
3867, int* pY
19193a2c 3868,wxFont* WXUNUSED(pTheFont)
61243a51 3869)
cdf1e714 3870{
987da0d4
DW
3871 FONTMETRICS vFM;
3872 HPS hPS;
3873 BOOL rc;
3874
3875 hPS =::WinGetPS(hWnd);
3876
3877 rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
3878 if (rc)
3879 {
3880 if (pX)
3881 *pX = vFM.lAveCharWidth;
3882 if (pY)
3883 *pY = vFM.lEmHeight + vFM.lExternalLeading;
3884 }
3885 else
3886 {
3887 if (pX)
3888 *pX = 10;
3889 if (pY)
3890 *pY = 15;
3891 }
3892 ::WinReleasePS(hPS);
61243a51 3893} // end of wxGetCharSize
cdf1e714 3894
61243a51 3895//
cdf1e714
DW
3896// Returns 0 if was a normal ASCII value, not a special key. This indicates that
3897// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
61243a51
DW
3898//
3899int wxCharCodeOS2ToWX(
3900 int nKeySym
3901)
cdf1e714 3902{
61243a51
DW
3903 int nId = 0;
3904
3905 switch (nKeySym)
3906 {
3907 case VK_BACKTAB: nId = WXK_BACK; break;
3908 case VK_TAB: nId = WXK_TAB; break;
3909 case VK_CLEAR: nId = WXK_CLEAR; break;
3910 case VK_ENTER: nId = WXK_RETURN; break;
3911 case VK_SHIFT: nId = WXK_SHIFT; break;
3912 case VK_CTRL: nId = WXK_CONTROL; break;
3913 case VK_PAUSE: nId = WXK_PAUSE; break;
3914 case VK_SPACE: nId = WXK_SPACE; break;
3915 case VK_ESC: nId = WXK_ESCAPE; break;
3916 case VK_END: nId = WXK_END; break;
3917 case VK_HOME : nId = WXK_HOME; break;
3918 case VK_LEFT : nId = WXK_LEFT; break;
3919 case VK_UP: nId = WXK_UP; break;
3920 case VK_RIGHT: nId = WXK_RIGHT; break;
3921 case VK_DOWN : nId = WXK_DOWN; break;
3922 case VK_PRINTSCRN: nId = WXK_PRINT; break;
3923 case VK_INSERT: nId = WXK_INSERT; break;
3924 case VK_DELETE: nId = WXK_DELETE; break;
3925 case VK_F1: nId = WXK_F1; break;
3926 case VK_F2: nId = WXK_F2; break;
3927 case VK_F3: nId = WXK_F3; break;
3928 case VK_F4: nId = WXK_F4; break;
3929 case VK_F5: nId = WXK_F5; break;
3930 case VK_F6: nId = WXK_F6; break;
3931 case VK_F7: nId = WXK_F7; break;
3932 case VK_F8: nId = WXK_F8; break;
3933 case VK_F9: nId = WXK_F9; break;
3934 case VK_F10: nId = WXK_F10; break;
3935 case VK_F11: nId = WXK_F11; break;
3936 case VK_F12: nId = WXK_F12; break;
3937 case VK_F13: nId = WXK_F13; break;
3938 case VK_F14: nId = WXK_F14; break;
3939 case VK_F15: nId = WXK_F15; break;
3940 case VK_F16: nId = WXK_F16; break;
3941 case VK_F17: nId = WXK_F17; break;
3942 case VK_F18: nId = WXK_F18; break;
3943 case VK_F19: nId = WXK_F19; break;
3944 case VK_F20: nId = WXK_F20; break;
3945 case VK_F21: nId = WXK_F21; break;
3946 case VK_F22: nId = WXK_F22; break;
3947 case VK_F23: nId = WXK_F23; break;
3948 case VK_F24: nId = WXK_F24; break;
3949 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
3950 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
3951 default:
86de7616 3952 {
cdf1e714 3953 return 0;
86de7616
DW
3954 }
3955 }
61243a51
DW
3956 return nId;
3957} // end of wxCharCodeOS2ToWX
86de7616 3958
61243a51
DW
3959int wxCharCodeWXToOS2(
3960 int nId
3961, bool* bIsVirtual
3962)
86de7616 3963{
61243a51
DW
3964 int nKeySym = 0;
3965
3966 *bIsVirtual = TRUE;
3967 switch (nId)
3968 {
3969 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
3970 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
3971 case WXK_CONTROL: nKeySym = VK_CTRL; break;
3972 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
3973 case WXK_END: nKeySym = VK_END; break;
3974 case WXK_HOME : nKeySym = VK_HOME; break;
3975 case WXK_LEFT : nKeySym = VK_LEFT; break;
3976 case WXK_UP: nKeySym = VK_UP; break;
3977 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
3978 case WXK_DOWN : nKeySym = VK_DOWN; break;
3979 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
3980 case WXK_INSERT: nKeySym = VK_INSERT; break;
3981 case WXK_DELETE: nKeySym = VK_DELETE; break;
3982 case WXK_F1: nKeySym = VK_F1; break;
3983 case WXK_F2: nKeySym = VK_F2; break;
3984 case WXK_F3: nKeySym = VK_F3; break;
3985 case WXK_F4: nKeySym = VK_F4; break;
3986 case WXK_F5: nKeySym = VK_F5; break;
3987 case WXK_F6: nKeySym = VK_F6; break;
3988 case WXK_F7: nKeySym = VK_F7; break;
3989 case WXK_F8: nKeySym = VK_F8; break;
3990 case WXK_F9: nKeySym = VK_F9; break;
3991 case WXK_F10: nKeySym = VK_F10; break;
3992 case WXK_F11: nKeySym = VK_F11; break;
3993 case WXK_F12: nKeySym = VK_F12; break;
3994 case WXK_F13: nKeySym = VK_F13; break;
3995 case WXK_F14: nKeySym = VK_F14; break;
3996 case WXK_F15: nKeySym = VK_F15; break;
3997 case WXK_F16: nKeySym = VK_F16; break;
3998 case WXK_F17: nKeySym = VK_F17; break;
3999 case WXK_F18: nKeySym = VK_F18; break;
4000 case WXK_F19: nKeySym = VK_F19; break;
4001 case WXK_F20: nKeySym = VK_F20; break;
4002 case WXK_F21: nKeySym = VK_F21; break;
4003 case WXK_F22: nKeySym = VK_F22; break;
4004 case WXK_F23: nKeySym = VK_F23; break;
4005 case WXK_F24: nKeySym = VK_F24; break;
4006 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
4007 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
4008 default:
cdf1e714 4009 {
61243a51
DW
4010 *bIsVirtual = FALSE;
4011 nKeySym = nId;
cdf1e714
DW
4012 break;
4013 }
86de7616 4014 }
61243a51
DW
4015 return nKeySym;
4016} // end of wxCharCodeWXToOS2
86de7616 4017
61243a51 4018wxWindow* wxGetActiveWindow()
cdf1e714 4019{
61243a51 4020 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
86de7616 4021
61243a51
DW
4022 if (hWnd != 0)
4023 {
4024 return wxFindWinFromHandle((WXHWND)hWnd);
4025 }
4026 return NULL;
4027} // end of wxGetActiveWindow
cdf1e714
DW
4028
4029#ifdef __WXDEBUG__
61243a51
DW
4030const char* wxGetMessageName(
4031 int nMessage)
cdf1e714 4032{
61243a51 4033 switch (nMessage)
86de7616 4034 {
cdf1e714
DW
4035 case 0x0000: return "WM_NULL";
4036 case 0x0001: return "WM_CREATE";
4037 case 0x0002: return "WM_DESTROY";
61243a51
DW
4038 case 0x0004: return "WM_ENABLE";
4039 case 0x0005: return "WM_SHOW";
4040 case 0x0006: return "WM_MOVE";
4041 case 0x0007: return "WM_SIZE";
4042 case 0x0008: return "WM_ADJUSTWINDOWPOS";
4043 case 0x0009: return "WM_CALCVALIDRECTS";
4044 case 0x000A: return "WM_SETWINDOWPARAMS";
4045 case 0x000B: return "WM_QUERYWINDOWPARAMS";
4046 case 0x000C: return "WM_HITTEST";
4047 case 0x000D: return "WM_ACTIVATE";
4048 case 0x000F: return "WM_SETFOCUS";
4049 case 0x0010: return "WM_SETSELECTION";
4050 case 0x0011: return "WM_PPAINT";
4051 case 0x0012: return "WM_PSETFOCUS";
4052 case 0x0013: return "WM_PSYSCOLORCHANGE";
4053 case 0x0014: return "WM_PSIZE";
4054 case 0x0015: return "WM_PACTIVATE";
4055 case 0x0016: return "WM_PCONTROL";
4056 case 0x0020: return "WM_COMMAND";
4057 case 0x0021: return "WM_SYSCOMMAND";
4058 case 0x0022: return "WM_HELP";
4059 case 0x0023: return "WM_PAINT";
4060 case 0x0024: return "WM_TIMER";
4061 case 0x0025: return "WM_SEM1";
4062 case 0x0026: return "WM_SEM2";
4063 case 0x0027: return "WM_SEM3";
4064 case 0x0028: return "WM_SEM4";
4065 case 0x0029: return "WM_CLOSE";
4066 case 0x002A: return "WM_QUIT";
4067 case 0x002B: return "WM_SYSCOLORCHANGE";
4068 case 0x002D: return "WM_SYSVALUECHANGE";
4069 case 0x002E: return "WM_APPTERMINATENOTIFY";
4070 case 0x002F: return "WM_PRESPARAMCHANGED";
4071 // Control notification messages
4072 case 0x0030: return "WM_CONTROL";
4073 case 0x0031: return "WM_VSCROLL";
4074 case 0x0032: return "WM_HSCROLL";
4075 case 0x0033: return "WM_INITMENU";
4076 case 0x0034: return "WM_MENUSELECT";
4077 case 0x0035: return "WM_MENUSEND";
4078 case 0x0036: return "WM_DRAWITEM";
4079 case 0x0037: return "WM_MEASUREITEM";
4080 case 0x0038: return "WM_CONTROLPOINTER";
4081 case 0x003A: return "WM_QUERYDLGCODE";
4082 case 0x003B: return "WM_INITDLG";
4083 case 0x003C: return "WM_SUBSTITUTESTRING";
4084 case 0x003D: return "WM_MATCHMNEMONIC";
4085 case 0x003E: return "WM_SAVEAPPLICATION";
4086 case 0x0129: return "WM_CTLCOLORCHANGE";
4087 case 0x0130: return "WM_QUERYCTLTYPE";
4088 // Frame messages
4089 case 0x0040: return "WM_FLASHWINDOW";
4090 case 0x0041: return "WM_FORMATFRAME";
4091 case 0x0042: return "WM_UPDATEFRAME";
4092 case 0x0043: return "WM_FOCUSCHANGE";
4093 case 0x0044: return "WM_SETBORDERSIZE";
4094 case 0x0045: return "WM_TRACKFRAME";
4095 case 0x0046: return "WM_MINMAXFRAME";
4096 case 0x0047: return "WM_SETICON";
4097 case 0x0048: return "WM_QUERYICON";
4098 case 0x0049: return "WM_SETACCELTABLE";
4099 case 0x004A: return "WM_QUERYACCELTABLE";
4100 case 0x004B: return "WM_TRANSLATEACCEL";
4101 case 0x004C: return "WM_QUERYTRACKINFO";
4102 case 0x004D: return "WM_QUERYBORDERSIZE";
4103 case 0x004E: return "WM_NEXTMENU";
4104 case 0x004F: return "WM_ERASEBACKGROUND";
4105 case 0x0050: return "WM_QUERYFRAMEINFO";
4106 case 0x0051: return "WM_QUERYFOCUSCHAIN";
4107 case 0x0052: return "WM_OWNERPOSCHANGE";
4108 case 0x0053: return "WM_CACLFRAMERECT";
4109 case 0x0055: return "WM_WINDOWPOSCHANGED";
4110 case 0x0056: return "WM_ADJUSTFRAMEPOS";
4111 case 0x0059: return "WM_QUERYFRAMECTLCOUNT";
4112 case 0x005B: return "WM_QUERYHELPINFO";
4113 case 0x005C: return "WM_SETHELPINFO";
4114 case 0x005D: return "WM_ERROR";
4115 case 0x005E: return "WM_REALIZEPALETTE";
4116 // Clipboard messages
4117 case 0x0060: return "WM_RENDERFMT";
4118 case 0x0061: return "WM_RENDERALLFMTS";
4119 case 0x0062: return "WM_DESTROYCLIPBOARD";
4120 case 0x0063: return "WM_PAINTCLIPBOARD";
4121 case 0x0064: return "WM_SIZECLIPBOARD";
4122 case 0x0065: return "WM_HSCROLLCLIPBOARD";
4123 case 0x0066: return "WM_VSCROLLCLIPBOARD";
4124 case 0x0067: return "WM_DRAWCLIPBOARD";
4125 // mouse messages
4126 case 0x0070: return "WM_MOUSEMOVE";
4127 case 0x0071: return "WM_BUTTON1DOWN";
4128 case 0x0072: return "WM_BUTTON1UP";
4129 case 0x0073: return "WM_BUTTON1DBLCLK";
4130 case 0x0074: return "WM_BUTTON2DOWN";
4131 case 0x0075: return "WM_BUTTON2UP";
4132 case 0x0076: return "WM_BUTTON2DBLCLK";
4133 case 0x0077: return "WM_BUTTON3DOWN";
4134 case 0x0078: return "WM_BUTTON3UP";
4135 case 0x0079: return "WM_BUTTON3DBLCLK";
4136 case 0x007D: return "WM_MOUSEMAP";
4137 case 0x007E: return "WM_VRNDISABLED";
4138 case 0x007F: return "WM_VRNENABLED";
4139 case 0x0410: return "WM_CHORD";
4140 case 0x0411: return "WM_BUTTON1MOTIONSTART";
4141 case 0x0412: return "WM_BUTTON1MOTIONEND";
4142 case 0x0413: return "WM_BUTTON1CLICK";
4143 case 0x0414: return "WM_BUTTON2MOTIONSTART";
4144 case 0x0415: return "WM_BUTTON2MOTIONEND";
4145 case 0x0416: return "WM_BUTTON2CLICK";
4146 case 0x0417: return "WM_BUTTON3MOTIONSTART";
4147 case 0x0418: return "WM_BUTTON3MOTIONEND";
4148 case 0x0419: return "WM_BUTTON3CLICK";
4149 case 0x0420: return "WM_BEGINDRAG";
4150 case 0x0421: return "WM_ENDDRAG";
4151 case 0x0422: return "WM_SINGLESELECT";
4152 case 0x0423: return "WM_OPEN";
4153 case 0x0424: return "WM_CONTEXTMENU";
4154 case 0x0425: return "WM_CONTEXTHELP";
4155 case 0x0426: return "WM_TEXTEDIT";
4156 case 0x0427: return "WM_BEGINSELECT";
4157 case 0x0228: return "WM_ENDSELECT";
4158 case 0x0429: return "WM_PICKUP";
4159 case 0x04C0: return "WM_PENFIRST";
4160 case 0x04FF: return "WM_PENLAST";
4161 case 0x0500: return "WM_MMPMFIRST";
4162 case 0x05FF: return "WM_MMPMLAST";
4163 case 0x0600: return "WM_STDDLGFIRST";
4164 case 0x06FF: return "WM_STDDLGLAST";
4165 case 0x0BD0: return "WM_BIDI_FIRST";
4166 case 0x0BFF: return "WM_BIDI_LAST";
4167 // keyboard input
4168 case 0x007A: return "WM_CHAR";
4169 case 0x007B: return "WM_VIOCHAR";
4170 // DDE messages
4171 case 0x00A0: return "WM_DDE_INITIATE";
4172 case 0x00A1: return "WM_DDE_REQUEST";
4173 case 0x00A2: return "WM_DDE_ACK";
4174 case 0x00A3: return "WM_DDE_DATA";
4175 case 0x00A4: return "WM_DDE_ADVISE";
4176 case 0x00A5: return "WM_DDE_UNADVISE";
4177 case 0x00A6: return "WM_DDE_POKE";
4178 case 0x00A7: return "WM_DDE_EXECUTE";
4179 case 0x00A8: return "WM_DDE_TERMINATE";
4180 case 0x00A9: return "WM_DDE_INITIATEACK";
4181 case 0x00AF: return "WM_DDE_LAST";
4182 // Buttons
4183 case 0x0120: return "BM_CLICK";
4184 case 0x0121: return "BM_QUERYCHECKINDEX";
4185 case 0x0122: return "BM_QUERYHILITE";
4186 case 0x0123: return "BM_SETHILITE";
4187 case 0x0124: return "BM_QUERYCHECK";
4188 case 0x0125: return "BM_SETCHECK";
4189 case 0x0126: return "BM_SETDEFAULT";
4190 case 0x0128: return "BM_AUTOSIZE";
4191 // Combo boxes
4192 case 0x029A: return "CBID_LIST";
4193 case 0x029B: return "CBID_EDIT";
4194 case 0x0170: return "CBM_SHOWLIST";
4195 case 0x0171: return "CBM_HILITE";
4196 case 0x0172: return "CBM_ISLISTSHOWING";
4197 // Edit fields
4198 case 0x0140: return "EM_QUERYCHANGED";
4199 case 0x0141: return "EM_QUERYSEL";
4200 case 0x0142: return "EM_SETSEL";
4201 case 0x0143: return "EM_SETTEXTLIMIT";
4202 case 0x0144: return "EM_CUT";
4203 case 0x0145: return "EM_COPY";
4204 case 0x0146: return "EM_CLEAR";
4205 case 0x0147: return "EM_PASTE";
4206 case 0x0148: return "EM_QUERYFIRSTCHAR";
4207 case 0x0149: return "EM_SETFIRSTCHAR";
4208 case 0x014A: return "EM_QUERYREADONLY";
4209 case 0x014B: return "EM_SETREADONLY";
4210 case 0x014C: return "EM_SETINSERTMODE";
4211 // Listboxes
4212 case 0x0160: return "LM_QUERYITEMCOUNT";
4213 case 0x0161: return "LM_INSERTITEM";
4214 case 0x0162: return "LM_SETOPENINDEX";
4215 case 0x0163: return "LM_DELETEITEM";
4216 case 0x0164: return "LM_SELECTITEM";
4217 case 0x0165: return "LM_QUERYSELECTION";
4218 case 0x0166: return "LM_SETITEMTEXT";
4219 case 0x0167: return "LM_QUERYITEMTEXTLENGTH";
4220 case 0x0168: return "LM_QUERYITEMTEXT";
4221 case 0x0169: return "LM_SETITEMHANDLE";
4222 case 0x016A: return "LM_QUERYITEMHANDLE";
4223 case 0x016B: return "LM_SEARCHSTRING";
4224 case 0x016C: return "LM_SETITEMHEIGHT";
4225 case 0x016D: return "LM_QUERYTOPINDEX";
4226 case 0x016E: return "LM_DELETEALL";
4227 case 0x016F: return "LM_INSERTMULITEMS";
4228 case 0x0660: return "LM_SETITEMWIDTH";
4229 // Menus
4230 case 0x0180: return "MM_INSERTITEM";
4231 case 0x0181: return "MM_DELETEITEM";
4232 case 0x0182: return "MM_QUERYITEM";
4233 case 0x0183: return "MM_SETITEM";
4234 case 0x0184: return "MM_QUERYITEMCOUNT";
4235 case 0x0185: return "MM_STARTMENUMODE";
4236 case 0x0186: return "MM_ENDMENUMODE";
4237 case 0x0188: return "MM_REMOVEITEM";
4238 case 0x0189: return "MM_SELECTITEM";
4239 case 0x018A: return "MM_QUERYSELITEMID";
4240 case 0x018B: return "MM_QUERYITEMTEXT";
4241 case 0x018C: return "MM_QUERYITEMTEXTLENGTH";
4242 case 0x018D: return "MM_SETITEMHANDLE";
4243 case 0x018E: return "MM_SETITEMTEXT";
4244 case 0x018F: return "MM_ITEMPOSITIONFROMID";
4245 case 0x0190: return "MM_ITEMIDFROMPOSITION";
4246 case 0x0191: return "MM_QUERYITEMATTR";
4247 case 0x0192: return "MM_SETITEMATTR";
4248 case 0x0193: return "MM_ISITEMVALID";
4249 case 0x0194: return "MM_QUERYITEMRECT";
4250 case 0x0431: return "MM_QUERYDEFAULTITEMID";
4251 case 0x0432: return "MM_SETDEFAULTITEMID";
4252 // Scrollbars
4253 case 0x01A0: return "SBM_SETSCROLLBAR";
4254 case 0x01A1: return "SBM_SETPOS";
4255 case 0x01A2: return "SBM_QUERYPOS";
4256 case 0x01A3: return "SBM_QUERYRANGE";
4257 case 0x01A6: return "SBM_SETTHUMBSIZE";
4258
4259 // Help messages
4260 case 0x0F00: return "WM_HELPBASE";
4261 case 0x0FFF: return "WM_HELPTOP";
4262 // Beginning of user defined messages
4263 case 0x1000: return "WM_USER";
4264
4265 // wxWindows user defined types
cdf1e714
DW
4266
4267 // listview
61243a51 4268 // case 0x1000 + 0: return "LVM_GETBKCOLOR";
cdf1e714
DW
4269 case 0x1000 + 1: return "LVM_SETBKCOLOR";
4270 case 0x1000 + 2: return "LVM_GETIMAGELIST";
4271 case 0x1000 + 3: return "LVM_SETIMAGELIST";
4272 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
4273 case 0x1000 + 5: return "LVM_GETITEMA";
4274 case 0x1000 + 75: return "LVM_GETITEMW";
4275 case 0x1000 + 6: return "LVM_SETITEMA";
4276 case 0x1000 + 76: return "LVM_SETITEMW";
4277 case 0x1000 + 7: return "LVM_INSERTITEMA";
4278 case 0x1000 + 77: return "LVM_INSERTITEMW";
4279 case 0x1000 + 8: return "LVM_DELETEITEM";
4280 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
4281 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
4282 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
4283 case 0x1000 + 12: return "LVM_GETNEXTITEM";
4284 case 0x1000 + 13: return "LVM_FINDITEMA";
4285 case 0x1000 + 83: return "LVM_FINDITEMW";
4286 case 0x1000 + 14: return "LVM_GETITEMRECT";
4287 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
4288 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
4289 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
4290 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
4291 case 0x1000 + 18: return "LVM_HITTEST";
4292 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
4293 case 0x1000 + 20: return "LVM_SCROLL";
4294 case 0x1000 + 21: return "LVM_REDRAWITEMS";
4295 case 0x1000 + 22: return "LVM_ARRANGE";
4296 case 0x1000 + 23: return "LVM_EDITLABELA";
4297 case 0x1000 + 118: return "LVM_EDITLABELW";
4298 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
4299 case 0x1000 + 25: return "LVM_GETCOLUMNA";
4300 case 0x1000 + 95: return "LVM_GETCOLUMNW";
4301 case 0x1000 + 26: return "LVM_SETCOLUMNA";
4302 case 0x1000 + 96: return "LVM_SETCOLUMNW";
4303 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
4304 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
4305 case 0x1000 + 28: return "LVM_DELETECOLUMN";
4306 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
4307 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
4308 case 0x1000 + 31: return "LVM_GETHEADER";
4309 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
4310 case 0x1000 + 34: return "LVM_GETVIEWRECT";
4311 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
4312 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
4313 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
4314 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
4315 case 0x1000 + 39: return "LVM_GETTOPINDEX";
4316 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
4317 case 0x1000 + 41: return "LVM_GETORIGIN";
4318 case 0x1000 + 42: return "LVM_UPDATE";
4319 case 0x1000 + 43: return "LVM_SETITEMSTATE";
4320 case 0x1000 + 44: return "LVM_GETITEMSTATE";
4321 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
4322 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
4323 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
4324 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
4325 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
4326 case 0x1000 + 48: return "LVM_SORTITEMS";
4327 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
4328 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
4329 case 0x1000 + 51: return "LVM_GETITEMSPACING";
4330 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
4331 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
4332 case 0x1000 + 53: return "LVM_SETICONSPACING";
4333 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
4334 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
4335 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
4336 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
4337 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
4338 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
4339 case 0x1000 + 60: return "LVM_SETHOTITEM";
4340 case 0x1000 + 61: return "LVM_GETHOTITEM";
4341 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
4342 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
4343 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
4344 case 0x1000 + 65: return "LVM_SETWORKAREA";
4345
4346 // tree view
4347 case 0x1100 + 0: return "TVM_INSERTITEMA";
4348 case 0x1100 + 50: return "TVM_INSERTITEMW";
4349 case 0x1100 + 1: return "TVM_DELETEITEM";
4350 case 0x1100 + 2: return "TVM_EXPAND";
4351 case 0x1100 + 4: return "TVM_GETITEMRECT";
4352 case 0x1100 + 5: return "TVM_GETCOUNT";
4353 case 0x1100 + 6: return "TVM_GETINDENT";
4354 case 0x1100 + 7: return "TVM_SETINDENT";
4355 case 0x1100 + 8: return "TVM_GETIMAGELIST";
4356 case 0x1100 + 9: return "TVM_SETIMAGELIST";
4357 case 0x1100 + 10: return "TVM_GETNEXTITEM";
4358 case 0x1100 + 11: return "TVM_SELECTITEM";
4359 case 0x1100 + 12: return "TVM_GETITEMA";
4360 case 0x1100 + 62: return "TVM_GETITEMW";
4361 case 0x1100 + 13: return "TVM_SETITEMA";
4362 case 0x1100 + 63: return "TVM_SETITEMW";
4363 case 0x1100 + 14: return "TVM_EDITLABELA";
4364 case 0x1100 + 65: return "TVM_EDITLABELW";
4365 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
4366 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
4367 case 0x1100 + 17: return "TVM_HITTEST";
4368 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
4369 case 0x1100 + 19: return "TVM_SORTCHILDREN";
4370 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
4371 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
4372 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
4373 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
4374 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
4375 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
4376 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
4377
4378 // header
4379 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
4380 case 0x1200 + 1: return "HDM_INSERTITEMA";
4381 case 0x1200 + 10: return "HDM_INSERTITEMW";
4382 case 0x1200 + 2: return "HDM_DELETEITEM";
4383 case 0x1200 + 3: return "HDM_GETITEMA";
4384 case 0x1200 + 11: return "HDM_GETITEMW";
4385 case 0x1200 + 4: return "HDM_SETITEMA";
4386 case 0x1200 + 12: return "HDM_SETITEMW";
4387 case 0x1200 + 5: return "HDM_LAYOUT";
4388 case 0x1200 + 6: return "HDM_HITTEST";
4389 case 0x1200 + 7: return "HDM_GETITEMRECT";
4390 case 0x1200 + 8: return "HDM_SETIMAGELIST";
4391 case 0x1200 + 9: return "HDM_GETIMAGELIST";
4392 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
4393 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
4394 case 0x1200 + 17: return "HDM_GETORDERARRAY";
4395 case 0x1200 + 18: return "HDM_SETORDERARRAY";
4396 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
4397
4398 // tab control
4399 case 0x1300 + 2: return "TCM_GETIMAGELIST";
4400 case 0x1300 + 3: return "TCM_SETIMAGELIST";
4401 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
4402 case 0x1300 + 5: return "TCM_GETITEMA";
4403 case 0x1300 + 60: return "TCM_GETITEMW";
4404 case 0x1300 + 6: return "TCM_SETITEMA";
4405 case 0x1300 + 61: return "TCM_SETITEMW";
4406 case 0x1300 + 7: return "TCM_INSERTITEMA";
4407 case 0x1300 + 62: return "TCM_INSERTITEMW";
4408 case 0x1300 + 8: return "TCM_DELETEITEM";
4409 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
4410 case 0x1300 + 10: return "TCM_GETITEMRECT";
4411 case 0x1300 + 11: return "TCM_GETCURSEL";
4412 case 0x1300 + 12: return "TCM_SETCURSEL";
4413 case 0x1300 + 13: return "TCM_HITTEST";
4414 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
4415 case 0x1300 + 40: return "TCM_ADJUSTRECT";
4416 case 0x1300 + 41: return "TCM_SETITEMSIZE";
4417 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
4418 case 0x1300 + 43: return "TCM_SETPADDING";
4419 case 0x1300 + 44: return "TCM_GETROWCOUNT";
4420 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
4421 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
4422 case 0x1300 + 47: return "TCM_GETCURFOCUS";
4423 case 0x1300 + 48: return "TCM_SETCURFOCUS";
4424 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
4425 case 0x1300 + 50: return "TCM_DESELECTALL";
4426
4427 // toolbar
61243a51
DW
4428 case WM_USER+1000+1: return "TB_ENABLEBUTTON";
4429 case WM_USER+1000+2: return "TB_CHECKBUTTON";
4430 case WM_USER+1000+3: return "TB_PRESSBUTTON";
4431 case WM_USER+1000+4: return "TB_HIDEBUTTON";
4432 case WM_USER+1000+5: return "TB_INDETERMINATE";
4433 case WM_USER+1000+9: return "TB_ISBUTTONENABLED";
4434 case WM_USER+1000+10: return "TB_ISBUTTONCHECKED";
4435 case WM_USER+1000+11: return "TB_ISBUTTONPRESSED";
4436 case WM_USER+1000+12: return "TB_ISBUTTONHIDDEN";
4437 case WM_USER+1000+13: return "TB_ISBUTTONINDETERMINATE";
4438 case WM_USER+1000+17: return "TB_SETSTATE";
4439 case WM_USER+1000+18: return "TB_GETSTATE";
4440 case WM_USER+1000+19: return "TB_ADDBITMAP";
4441 case WM_USER+1000+20: return "TB_ADDBUTTONS";
4442 case WM_USER+1000+21: return "TB_INSERTBUTTON";
4443 case WM_USER+1000+22: return "TB_DELETEBUTTON";
4444 case WM_USER+1000+23: return "TB_GETBUTTON";
4445 case WM_USER+1000+24: return "TB_BUTTONCOUNT";
4446 case WM_USER+1000+25: return "TB_COMMANDTOINDEX";
4447 case WM_USER+1000+26: return "TB_SAVERESTOREA";
4448 case WM_USER+1000+76: return "TB_SAVERESTOREW";
4449 case WM_USER+1000+27: return "TB_CUSTOMIZE";
4450 case WM_USER+1000+28: return "TB_ADDSTRINGA";
4451 case WM_USER+1000+77: return "TB_ADDSTRINGW";
4452 case WM_USER+1000+29: return "TB_GETITEMRECT";
4453 case WM_USER+1000+30: return "TB_BUTTONSTRUCTSIZE";
4454 case WM_USER+1000+31: return "TB_SETBUTTONSIZE";
4455 case WM_USER+1000+32: return "TB_SETBITMAPSIZE";
4456 case WM_USER+1000+33: return "TB_AUTOSIZE";
4457 case WM_USER+1000+35: return "TB_GETTOOLTIPS";
4458 case WM_USER+1000+36: return "TB_SETTOOLTIPS";
4459 case WM_USER+1000+37: return "TB_SETPARENT";
4460 case WM_USER+1000+39: return "TB_SETROWS";
4461 case WM_USER+1000+40: return "TB_GETROWS";
4462 case WM_USER+1000+42: return "TB_SETCMDID";
4463 case WM_USER+1000+43: return "TB_CHANGEBITMAP";
4464 case WM_USER+1000+44: return "TB_GETBITMAP";
4465 case WM_USER+1000+45: return "TB_GETBUTTONTEXTA";
4466 case WM_USER+1000+75: return "TB_GETBUTTONTEXTW";
4467 case WM_USER+1000+46: return "TB_REPLACEBITMAP";
4468 case WM_USER+1000+47: return "TB_SETINDENT";
4469 case WM_USER+1000+48: return "TB_SETIMAGELIST";
4470 case WM_USER+1000+49: return "TB_GETIMAGELIST";
4471 case WM_USER+1000+50: return "TB_LOADIMAGES";
4472 case WM_USER+1000+51: return "TB_GETRECT";
4473 case WM_USER+1000+52: return "TB_SETHOTIMAGELIST";
4474 case WM_USER+1000+53: return "TB_GETHOTIMAGELIST";
4475 case WM_USER+1000+54: return "TB_SETDISABLEDIMAGELIST";
4476 case WM_USER+1000+55: return "TB_GETDISABLEDIMAGELIST";
4477 case WM_USER+1000+56: return "TB_SETSTYLE";
4478 case WM_USER+1000+57: return "TB_GETSTYLE";
4479 case WM_USER+1000+58: return "TB_GETBUTTONSIZE";
4480 case WM_USER+1000+59: return "TB_SETBUTTONWIDTH";
4481 case WM_USER+1000+60: return "TB_SETMAXTEXTROWS";
4482 case WM_USER+1000+61: return "TB_GETTEXTROWS";
4483 case WM_USER+1000+41: return "TB_GETBITMAPFLAGS";
cdf1e714
DW
4484
4485 default:
4486 static char s_szBuf[128];
61243a51 4487 sprintf(s_szBuf, "<unknown message = %d>", nMessage);
cdf1e714 4488 return s_szBuf;
86de7616 4489 }
cdf1e714 4490 return NULL;
61243a51 4491} // end of wxGetMessageName
86de7616 4492
11e59d47
DW
4493#endif // __WXDEBUG__
4494
19193a2c
KB
4495// Unused?
4496#if 0
61243a51
DW
4497static void TranslateKbdEventToMouse(
4498 wxWindow* pWin
4499, int* pX
4500, int* pY
4501, ULONG* pFlags
4502)
4503{
4504 //
4505 // Construct the key mask
4506 ULONG& fwKeys = *pFlags;
4507
4508 fwKeys = VK_BUTTON2;
4509 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
4510 fwKeys |= VK_CTRL;
4511 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
4512 fwKeys |= VK_SHIFT;
4513
4514 //
4515 // Simulate right mouse button click
4516 //
4517 POINTL vPoint;
4518
4519 ::WinQueryMsgPos(vHabmain, &vPoint);
4520 *pX = vPoint.x;
4521 *pY = vPoint.y;
4522
4523 pWin->ScreenToClient(pX, pY);
4524} // end of TranslateKbdEventToMouse
19193a2c 4525#endif
61243a51 4526
cd212ee4
DW
4527// Find the wxWindow at the current mouse position, returning the mouse
4528// position.
f44fdfb0 4529wxWindow* wxFindWindowAtPointer(
19193a2c 4530 wxPoint& WXUNUSED(rPt)
f44fdfb0 4531)
cd212ee4
DW
4532{
4533 return wxFindWindowAtPoint(wxGetMousePosition());
4534}
4535
f44fdfb0
DW
4536wxWindow* wxFindWindowAtPoint(
4537 const wxPoint& rPt
4538)
cd212ee4 4539{
f44fdfb0 4540 POINTL vPt2;
cd212ee4 4541
f44fdfb0
DW
4542 vPt2.x = rPt.x;
4543 vPt2.y = rPt.y;
cd212ee4 4544
f44fdfb0
DW
4545 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
4546 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
4547 HWND hWnd = hWndHit;
4548
4549 //
cd212ee4 4550 // Try to find a window with a wxWindow associated with it
f44fdfb0
DW
4551 //
4552 while (!pWin && (hWnd != 0))
cd212ee4 4553 {
f44fdfb0
DW
4554 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
4555 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
cd212ee4 4556 }
f44fdfb0 4557 return pWin;
cd212ee4
DW
4558}
4559
f44fdfb0
DW
4560// Get the current mouse position.
4561wxPoint wxGetMousePosition()
4562{
4563 POINTL vPt;
4564
4565 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
4566 return wxPoint(vPt.x, vPt.y);
4567}
cd212ee4 4568