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