]> git.saurik.com Git - wxWidgets.git/blame - src/os2/window.cpp
Applied patch sent to me for xpmdecod.cpp/VC++ compilation, and changed
[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{
8d7ddd02 1457#if 0 // x and y coords should already be in os2 coordinates
39c26ef2
DW
1458 RECTL vRect;
1459 HWND hParent;
1460 wxWindow* pParent = GetParent();
1461
1462 if (pParent)
1463 hParent = GetWinHwnd(pParent);
1464 else
1465 hParent = HWND_DESKTOP;
1466 ::WinQueryWindowRect(hParent, &vRect);
1467 nY = vRect.yTop - (nY + nHeight);
8d7ddd02 1468#endif
542875a8
DW
1469 if ( !::WinSetWindowPos( GetHwnd()
1470 ,HWND_TOP
1471 ,(LONG)nX
1472 ,(LONG)nY
1473 ,(LONG)nWidth
1474 ,(LONG)nHeight
1475 ,SWP_SIZE | SWP_MOVE
1476 ))
c86c44a0
DW
1477 {
1478 wxLogLastError("MoveWindow");
1479 }
0367c1c0 1480} // end of wxWindowOS2::DoMoveWindow
cdf1e714 1481
c86c44a0
DW
1482//
1483// Set the size of the window: if the dimensions are positive, just use them,
cdf1e714
DW
1484// but if any of them is equal to -1, it means that we must find the value for
1485// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1486// which case -1 is a valid value for x and y)
1487//
1488// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1489// the width/height to best suit our contents, otherwise we reuse the current
1490// width/height
c86c44a0 1491//
0367c1c0 1492void wxWindowOS2::DoSetSize(
a7ef993c
DW
1493 int nX
1494, int nY
1495, int nWidth
1496, int nHeight
1497, int nSizeFlags
1498)
cdf1e714 1499{
a7ef993c
DW
1500 //
1501 // Get the current size and position...
1502 //
1503 int nCurrentX;
1504 int nCurrentY;
1505 int nCurrentWidth;
1506 int nCurrentHeight;
542875a8 1507 wxSize vSize(-1, -1);
a7ef993c
DW
1508
1509 GetPosition( &nCurrentX
1510 ,&nCurrentY
1511 );
1512 GetSize( &nCurrentWidth
1513 ,&nCurrentHeight
1514 );
c86c44a0 1515
a7ef993c 1516 //
c86c44a0 1517 // ... and don't do anything (avoiding flicker) if it's already ok
a7ef993c 1518 //
542875a8 1519 if ( nX == nCurrentX &&
a7ef993c 1520 nY == nCurrentY &&
542875a8 1521 nWidth == nCurrentWidth &&
a7ef993c
DW
1522 nHeight == nCurrentHeight
1523 )
c86c44a0
DW
1524 {
1525 return;
1526 }
1527
a7ef993c
DW
1528 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1529 nX = nCurrentX;
542875a8 1530 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
a7ef993c 1531 nY = nCurrentY;
c86c44a0 1532
a7ef993c
DW
1533 AdjustForParentClientOrigin( nX
1534 ,nY
1535 ,nSizeFlags
1536 );
c86c44a0 1537
a7ef993c 1538 if (nWidth == -1)
c86c44a0 1539 {
a7ef993c 1540 if (nSizeFlags & wxSIZE_AUTO_WIDTH)
c86c44a0 1541 {
a7ef993c
DW
1542 vSize = DoGetBestSize();
1543 nWidth = vSize.x;
c86c44a0
DW
1544 }
1545 else
1546 {
a7ef993c
DW
1547 //
1548 // Just take the current one
1549 //
1550 nWidth = nCurrentWidth;
c86c44a0
DW
1551 }
1552 }
1553
a7ef993c 1554 if (nHeight == -1)
c86c44a0 1555 {
a7ef993c 1556 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
c86c44a0 1557 {
a7ef993c 1558 if (vSize.x == -1)
c86c44a0 1559 {
a7ef993c 1560 vSize = DoGetBestSize();
c86c44a0 1561 }
a7ef993c 1562 nHeight = vSize.y;
c86c44a0
DW
1563 }
1564 else
1565 {
1566 // just take the current one
a7ef993c 1567 nHeight = nCurrentHeight;
c86c44a0
DW
1568 }
1569 }
1570
a7ef993c
DW
1571 DoMoveWindow( nX
1572 ,nY
1573 ,nWidth
1574 ,nHeight
1575 );
0367c1c0 1576} // end of wxWindowOS2::DoSetSize
cdf1e714 1577
0367c1c0 1578void wxWindowOS2::DoSetClientSize(
a7ef993c
DW
1579 int nWidth
1580, int nHeight
1581)
cdf1e714 1582{
a7ef993c
DW
1583 wxWindow* pParent = GetParent();
1584 HWND hWnd = GetHwnd();
1585 HWND hParentWnd = (HWND)0;
1586 HWND hClientWnd = (HWND)0;
1587 RECTL vRect;
1588 RECT vRect2;
1589 RECT vRect3;
c86c44a0 1590
542875a8 1591 hClientWnd = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
a7ef993c 1592 ::WinQueryWindowRect(hClientWnd, &vRect2);
c86c44a0 1593
a7ef993c
DW
1594 if (pParent)
1595 hParentWnd = (HWND) pParent->GetHWND();
c86c44a0 1596
a7ef993c
DW
1597 ::WinQueryWindowRect(hWnd, &vRect);
1598 ::WinQueryWindowRect(hParentWnd, &vRect3);
1599 //
c86c44a0
DW
1600 // Find the difference between the entire window (title bar and all)
1601 // and the client area; add this to the new client size to move the
a7ef993c
DW
1602 // window. OS/2 is backward from windows on height
1603 //
1604 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
1605 int nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
c86c44a0 1606
a7ef993c
DW
1607 //
1608 // If there's a parent, must subtract the parent's bottom left corner
c86c44a0 1609 // since MoveWindow moves relative to the parent
a7ef993c
DW
1610 //
1611 POINTL vPoint;
c86c44a0 1612
a7ef993c
DW
1613 vPoint.x = vRect2.xLeft;
1614 vPoint.y = vRect2.yBottom;
1615 if (pParent)
c86c44a0 1616 {
a7ef993c 1617 vPoint.x -= vRect3.xLeft;
542875a8 1618 vPoint.y -= vRect3.yBottom;
c86c44a0
DW
1619 }
1620
a7ef993c
DW
1621 DoMoveWindow( vPoint.x
1622 ,vPoint.y
1623 ,nActualWidth
1624 ,nActualHeight
1625 );
c86c44a0 1626
a7ef993c
DW
1627 wxSizeEvent vEvent( wxSize( nWidth
1628 ,nHeight
1629 )
1630 ,m_windowId
1631 );
1632
1633 vEvent.SetEventObject(this);
1634 GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 1635} // end of wxWindowOS2::DoSetClientSize
cdf1e714 1636
0367c1c0 1637wxPoint wxWindowOS2::GetClientAreaOrigin() const
cdf1e714
DW
1638{
1639 return wxPoint(0, 0);
0367c1c0 1640} // end of wxWindowOS2::GetClientAreaOrigin
cdf1e714 1641
cdf1e714
DW
1642// ---------------------------------------------------------------------------
1643// text metrics
1644// ---------------------------------------------------------------------------
1645
0367c1c0 1646int wxWindowOS2::GetCharHeight() const
cdf1e714 1647{
a7ef993c
DW
1648 HPS hPs;
1649 FONTMETRICS vFontMetrics;
1650 BOOL bRc;
cdf1e714 1651
a7ef993c
DW
1652 hPs = ::WinGetPS(GetHwnd());
1653
542875a8 1654 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1655 {
1656 ::WinReleasePS(hPs);
a7ef993c 1657 return (0);
b7084589 1658 }
a7ef993c 1659 ::WinReleasePS(hPs);
b7084589 1660 return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender);
0367c1c0 1661} // end of wxWindowOS2::GetCharHeight
a7ef993c 1662
0367c1c0 1663int wxWindowOS2::GetCharWidth() const
cdf1e714 1664{
542875a8
DW
1665 HPS hPs;
1666 FONTMETRICS vFontMetrics;
1667
a7ef993c 1668 hPs = ::WinGetPS(GetHwnd());
cdf1e714 1669
542875a8 1670 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
b7084589
DW
1671 {
1672 ::WinReleasePS(hPs);
a7ef993c 1673 return (0);
b7084589 1674 }
a7ef993c 1675 ::WinReleasePS(hPs);
b7084589 1676 return(vFontMetrics.lAveCharWidth);
0367c1c0 1677} // end of wxWindowOS2::GetCharWidth
a7ef993c 1678
0367c1c0 1679void wxWindowOS2::GetTextExtent(
a7ef993c
DW
1680 const wxString& rString
1681, int* pX
1682, int* pY
1683, int* pDescent
1684, int* pExternalLeading
1685, const wxFont* pTheFont
1686) const
cdf1e714 1687{
a7ef993c
DW
1688 const wxFont* pFontToUse = pTheFont;
1689 HPS hPs;
1690
1691 hPs = ::WinGetPS(GetHwnd());
1692/*
1693// TODO: Will have to play with fonts later
1694
1695 if (!pFontToUse)
1696 pFontToUse = &m_font;
1697
1698 HFONT hFnt = 0;
1699 HFONT hFfontOld = 0;
1700
1701 if (pFontToUse && pFontToUse->Ok())
1702 {
1703 ::GpiCreateLog
1704 hFnt = (HFONT)((wxFont *)pFontToUse)->GetResourceHandle(); // const_cast
1705 if (hFnt)
1706 hFontOld = (HFONT)SelectObject(dc,fnt);
1707 }
1708
1709 SIZE sizeRect;
1710 TEXTMETRIC tm;
1711 GetTextExtentPoint(dc, string, (int)string.Length(), &sizeRect);
1712 GetTextMetrics(dc, &tm);
1713
1714 if ( fontToUse && fnt && hfontOld )
1715 SelectObject(dc, hfontOld);
1716
1717 ReleaseDC(hWnd, dc);
1718
1719 if ( x )
1720 *x = sizeRect.cx;
1721 if ( y )
1722 *y = sizeRect.cy;
1723 if ( descent )
1724 *descent = tm.tmDescent;
1725 if ( externalLeading )
1726 *externalLeading = tm.tmExternalLeading;
1727*/
1728 ::WinReleasePS(hPs);
cdf1e714
DW
1729}
1730
1731#if wxUSE_CARET && WXWIN_COMPATIBILITY
1732// ---------------------------------------------------------------------------
1733// Caret manipulation
1734// ---------------------------------------------------------------------------
1735
0367c1c0 1736void wxWindowOS2::CreateCaret(
a7ef993c
DW
1737 int nWidth
1738, int nHeight
1739)
cdf1e714 1740{
a7ef993c
DW
1741 SetCaret(new wxCaret( this
1742 ,nWidth
1743 ,nHeight
1744 ));
0367c1c0 1745} // end of wxWindowOS2::CreateCaret
a7ef993c 1746
0367c1c0 1747void wxWindowOS2::CreateCaret(
a7ef993c
DW
1748 const wxBitmap* pBitmap
1749)
cdf1e714 1750{
a7ef993c 1751 wxFAIL_MSG("not implemented");
0367c1c0 1752} // end of wxWindowOS2::CreateCaret
cdf1e714 1753
0367c1c0 1754void wxWindowOS2::ShowCaret(
a7ef993c
DW
1755 bool bShow
1756)
cdf1e714 1757{
a7ef993c
DW
1758 wxCHECK_RET( m_caret, "no caret to show" );
1759
1760 m_caret->Show(bShow);
0367c1c0 1761} // end of wxWindowOS2::ShowCaret
cdf1e714 1762
0367c1c0 1763void wxWindowOS2::DestroyCaret()
cdf1e714 1764{
a7ef993c 1765 SetCaret(NULL);
0367c1c0 1766} // end of wxWindowOS2::DestroyCaret
cdf1e714 1767
0367c1c0 1768void wxWindowOS2::SetCaretPos(
a7ef993c
DW
1769 int nX
1770, int nY)
cdf1e714 1771{
a7ef993c
DW
1772 wxCHECK_RET( m_caret, "no caret to move" );
1773
1774 m_caret->Move( nX
1775 ,nY
1776 );
0367c1c0 1777} // end of wxWindowOS2::SetCaretPos
cdf1e714 1778
0367c1c0 1779void wxWindowOS2::GetCaretPos(
a7ef993c
DW
1780 int* pX
1781, int* pY
1782) const
cdf1e714 1783{
a7ef993c
DW
1784 wxCHECK_RET( m_caret, "no caret to get position of" );
1785
1786 m_caret->GetPosition( pX
1787 ,pY
1788 );
0367c1c0 1789} // end of wxWindowOS2::GetCaretPos
cdf1e714
DW
1790
1791#endif //wxUSE_CARET
1792
1793// ---------------------------------------------------------------------------
1794// popup menu
1795// ---------------------------------------------------------------------------
1796
3febf684
DW
1797static void wxYieldForCommandsOnly()
1798{
1799 //
1800 // Peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
1801 // want to process it here)
1802 //
1803 QMSG vMsg;
1804
1805 while (::WinPeekMsg( vHabmain
1806 ,&vMsg
1807 ,(HWND)0
1808 ,WM_COMMAND
1809 ,WM_COMMAND
1810 ,PM_REMOVE
1811 ) && vMsg.msg != WM_QUIT)
1812 {
1813 wxTheApp->DoMessage((WXMSG*)&vMsg);
1814 }
1815}
1816
0367c1c0 1817bool wxWindowOS2::DoPopupMenu(
61243a51
DW
1818 wxMenu* pMenu
1819, int nX
1820, int nY
1821)
cdf1e714 1822{
61243a51
DW
1823 HWND hWnd = GetHwnd();
1824 HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
1825 HWND hMenu = GetHmenuOf(pMenu);
1826
1827 pMenu->SetInvokingWindow(this);
1828 pMenu->UpdateUI();
1829
1830 DoClientToScreen( &nX
1831 ,&nY
1832 );
1833 wxCurrentPopupMenu = pMenu;
1834
1835 ::WinPopupMenu( hWndParent
1836 ,hWnd
1837 ,hMenu
1838 ,nX
1839 ,nY
1840 ,0L
1841 ,PU_MOUSEBUTTON2DOWN | PU_MOUSEBUTTON2 | PU_KEYBOARD
1842 );
3febf684
DW
1843 // we need to do it righ now as otherwise the events are never going to be
1844 // sent to wxCurrentPopupMenu from HandleCommand()
1845 //
1846 // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
1847 // help and we'd still need wxYieldForCommandsOnly() as the menu may be
1848 // destroyed as soon as we return (it can be a local variable in the caller
1849 // for example) and so we do need to process the event immediately
1850 wxYieldForCommandsOnly();
61243a51
DW
1851 wxCurrentPopupMenu = NULL;
1852
1853 pMenu->SetInvokingWindow(NULL);
1854 return TRUE;
0367c1c0 1855} // end of wxWindowOS2::DoPopupMenu
cdf1e714
DW
1856
1857// ===========================================================================
1858// pre/post message processing
1859// ===========================================================================
1860
0367c1c0 1861MRESULT wxWindowOS2::OS2DefWindowProc(
61243a51
DW
1862 WXUINT uMsg
1863, WXWPARAM wParam
1864, WXLPARAM lParam
1865)
cdf1e714 1866{
61243a51 1867 if (m_fnOldWndProc)
e604d44b 1868 return (MRESULT)m_fnOldWndProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam);
61243a51 1869 else
e604d44b 1870 return ::WinDefWindowProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam);
0367c1c0 1871} // end of wxWindowOS2::OS2DefWindowProc
cdf1e714 1872
0367c1c0 1873bool wxWindowOS2::OS2ProcessMessage(
61243a51
DW
1874 WXMSG* pMsg
1875)
cdf1e714 1876{
61243a51
DW
1877 QMSG* pQMsg = (QMSG*)pMsg;
1878
1879 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
1880 {
1881 //
1882 // Intercept dialog navigation keys
1883 //
1884 bool bProcess = TRUE;
1885 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
1886
1887 if (uKeyFlags & KC_KEYUP)
1888 bProcess = FALSE;
1889
1890 if (uKeyFlags & KC_ALT)
1891 bProcess = FALSE;
1892
1893 if (!(uKeyFlags & KC_VIRTUALKEY))
1894 bProcess = FALSE;
1895
1896 if (bProcess)
1897 {
1898 bool bCtrlDown = IsCtrlDown();
1899 bool bShiftDown = IsShiftDown();
1900
1901 //
1902 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
1903 // don't process it if it's the case (except for Ctrl-Tab/Enter
1904 // combinations which are always processed)
1905 //
1906 ULONG ulDlgCode = 0;
1907
1908 if (!bCtrlDown)
1909 {
1910 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
1911 }
1912
1913 bool bForward = TRUE;
1914 bool bWindowChange = FALSE;
1915
1916 switch (SHORT2FROMMP(pQMsg->mp2))
1917 {
1918 //
1919 // Going to make certain assumptions about specific types of controls
1920 // here, so we may have to alter some things later if they prove invalid
1921 //
1922 case VK_TAB:
1923 //
1924 // Shift tabl will always be a nav-key but tabs may be wanted
1925 //
1926 if (!bShiftDown)
1927 {
1928 bProcess = FALSE;
1929 }
1930 else
1931 {
1932 //
1933 // Entry Fields want tabs for themselve usually
1934 //
1935 switch (ulDlgCode)
1936 {
1937 case DLGC_ENTRYFIELD:
1938 case DLGC_MLE:
1939 bProcess = TRUE;
1940 break;
1941
1942 default:
1943 bProcess = FALSE;
1944 }
1945
1946 //
1947 // Ctrl-Tab cycles thru notebook pages
1948 //
1949 bWindowChange = bCtrlDown;
1950 bForward = !bShiftDown;
1951 }
1952 break;
1953
1954 case VK_UP:
1955 case VK_LEFT:
1956 if (bCtrlDown)
1957 bProcess = FALSE;
1958 else
1959 bForward = FALSE;
1960 break;
1961
1962 case VK_DOWN:
1963 case VK_RIGHT:
1964 if (bCtrlDown)
1965 bProcess = FALSE;
1966 break;
1967
1968 case VK_ENTER:
1969 {
1970 if (bCtrlDown)
1971 {
1972 //
1973 // ctrl-enter is not processed
1974 //
1975 return FALSE;
1976 }
1977 else if (ulDlgCode & DLGC_BUTTON)
1978 {
1979 //
1980 // buttons want process Enter themselevs
1981 //
1982 bProcess = FALSE;
1983 }
1984 else
1985 {
1bcfc0e1
DW
1986 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
1987 ,wxButton
1988 );
61243a51
DW
1989
1990 if (pBtn && pBtn->IsEnabled())
1991 {
1992 //
1993 // If we do have a default button, do press it
1994 //
1995 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
1996 return TRUE;
1997 }
1998 // else: but if it does not it makes sense to make
1999 // it work like a TAB - and that's what we do.
2000 // Note that Ctrl-Enter always works this way.
2001 }
2002 }
2003 break;
2004
2005 default:
2006 bProcess = FALSE;
2007 }
2008
2009 if (bProcess)
2010 {
2011 wxNavigationKeyEvent vEvent;
2012
2013 vEvent.SetDirection(bForward);
2014 vEvent.SetWindowChange(bWindowChange);
2015 vEvent.SetEventObject(this);
2016
2017 if (GetEventHandler()->ProcessEvent(vEvent))
2018 {
2019 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2020
2021 if (pBtn)
2022 {
2023 //
2024 // The button which has focus should be default
2025 //
2026 pBtn->SetDefault();
2027 }
2028 return TRUE;
2029 }
2030 }
2031 }
dae16775
DW
2032 //
2033 // Let Dialogs process
2034 //
2035 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
2036 return TRUE;
61243a51 2037 }
61243a51
DW
2038
2039#if wxUSE_TOOLTIPS
2040 if ( m_tooltip )
2041 {
2042 // relay mouse move events to the tooltip control
2043 QMSG* pQMsg = (QMSG*)pMsg;
2044
2045 if (pQMsg->msg == WM_MOUSEMOVE )
2046 m_tooltip->RelayEvent(pMsg);
2047 }
2048#endif // wxUSE_TOOLTIPS
2049
cdf1e714 2050 return FALSE;
0367c1c0 2051} // end of wxWindowOS2::OS2ProcessMessage
cdf1e714 2052
0367c1c0 2053bool wxWindowOS2::OS2TranslateMessage(
61243a51
DW
2054 WXMSG* pMsg
2055)
cdf1e714 2056{
7e99520b
DW
2057#if wxUSE_ACCEL
2058 return m_acceleratorTable.Translate(m_hWnd, pMsg);
2059#else
2060 return FALSE;
2061#endif //wxUSE_ACCEL
0367c1c0 2062} // end of wxWindowOS2::OS2TranslateMessage
cdf1e714
DW
2063
2064// ---------------------------------------------------------------------------
61243a51 2065// message params unpackers
cdf1e714
DW
2066// ---------------------------------------------------------------------------
2067
0367c1c0 2068void wxWindowOS2::UnpackCommand(
61243a51
DW
2069 WXWPARAM wParam
2070, WXLPARAM lParam
2071, WORD* pId
2072, WXHWND* phWnd
2073, WORD* pCmd
2074)
cdf1e714 2075{
5b3ed311
DW
2076 *pId = LOWORD(wParam);
2077 *phWnd = NULL; // or may be GetHWND() ?
2078 *pCmd = LOWORD(lParam);
0367c1c0 2079} // end of wxWindowOS2::UnpackCommand
cdf1e714 2080
0367c1c0 2081void wxWindowOS2::UnpackActivate(
61243a51
DW
2082 WXWPARAM wParam
2083, WXLPARAM lParam
2084, WXWORD* pState
2085, WXHWND* phWnd
2086)
cdf1e714 2087{
61243a51
DW
2088 *pState = LOWORD(wParam);
2089 *phWnd = (WXHWND)lParam;
0367c1c0 2090} // end of wxWindowOS2::UnpackActivate
cdf1e714 2091
0367c1c0 2092void wxWindowOS2::UnpackScroll(
61243a51
DW
2093 WXWPARAM wParam
2094, WXLPARAM lParam
2095, WXWORD* pCode
2096, WXWORD* pPos
2097, WXHWND* phWnd
2098)
cdf1e714 2099{
b7d8f285
DW
2100 ULONG ulId;
2101 HWND hWnd;
2102
2103 ulId = (ULONG)LONGFROMMP(wParam);
2104 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2105 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2106 *phWnd = NULLHANDLE;
2107 else
2108 *phWnd = hWnd;
2109
2110 *pPos = SHORT1FROMMP(lParam);
2111 *pCode = SHORT2FROMMP(lParam);
0367c1c0 2112} // end of wxWindowOS2::UnpackScroll
61243a51 2113
0367c1c0 2114void wxWindowOS2::UnpackMenuSelect(
61243a51
DW
2115 WXWPARAM wParam
2116, WXLPARAM lParam
2117, WXWORD* pItem
2118, WXWORD* pFlags
2119, WXHMENU* phMenu
2120)
cdf1e714 2121{
61243a51
DW
2122 *pItem = (WXWORD)LOWORD(wParam);
2123 *pFlags = HIWORD(wParam);
2124 *phMenu = (WXHMENU)lParam;
0367c1c0 2125} // end of wxWindowOS2::UnpackMenuSelect
cdf1e714
DW
2126
2127// ---------------------------------------------------------------------------
2128// Main wxWindows window proc and the window proc for wxWindow
2129// ---------------------------------------------------------------------------
2130
61243a51 2131//
cdf1e714
DW
2132// Hook for new window just as it's being created, when the window isn't yet
2133// associated with the handle
61243a51
DW
2134//
2135wxWindow* wxWndHook = NULL;
cdf1e714 2136
61243a51 2137//
cdf1e714 2138// Main window proc
61243a51 2139//
f23208ca 2140MRESULT EXPENTRY wxWndProc(
61243a51
DW
2141 HWND hWnd
2142, ULONG ulMsg
2143, MPARAM wParam
2144, MPARAM lParam
2145)
cdf1e714 2146{
61243a51
DW
2147 //
2148 // Trace all ulMsgs - useful for the debugging
2149 //
cdf1e714
DW
2150#ifdef __WXDEBUG__
2151 wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
61243a51 2152 wxGetMessageName(ulMsg), wParam, lParam);
cdf1e714
DW
2153#endif // __WXDEBUG__
2154
61243a51 2155 wxWindow* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
cdf1e714 2156
61243a51
DW
2157 //
2158 // When we get the first message for the HWND we just created, we associate
cdf1e714 2159 // it with wxWindow stored in wxWndHook
61243a51
DW
2160 //
2161 if (!pWnd && wxWndHook)
cdf1e714 2162 {
cdf1e714 2163 wxAssociateWinWithHandle(hWnd, wxWndHook);
61243a51 2164 pWnd = wxWndHook;
cdf1e714 2165 wxWndHook = NULL;
61243a51 2166 pWnd->SetHWND((WXHWND)hWnd);
cdf1e714
DW
2167 }
2168
5b3ed311 2169 MRESULT rc = (MRESULT)0;
e604d44b 2170
cdf1e714 2171
61243a51 2172 //
cdf1e714 2173 // Stop right here if we don't have a valid handle in our wxWindow object.
61243a51
DW
2174 //
2175 if (pWnd && !pWnd->GetHWND())
cdf1e714 2176 {
61243a51
DW
2177 pWnd->SetHWND((WXHWND) hWnd);
2178 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2179 pWnd->SetHWND(0);
cdf1e714
DW
2180 }
2181 else
2182 {
61243a51
DW
2183 if (pWnd)
2184 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
e604d44b 2185 else
61243a51 2186 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
cdf1e714 2187 }
5b3ed311 2188
cdf1e714 2189 return rc;
61243a51 2190} // end of wxWndProc
cdf1e714 2191
61243a51
DW
2192//
2193// We will add (or delete) messages we need to handle at this default
2194// level as we go
2195//
0367c1c0 2196MRESULT wxWindowOS2::OS2WindowProc(
61243a51
DW
2197 WXUINT uMsg
2198, WXWPARAM wParam
2199, WXLPARAM lParam
2200)
cdf1e714 2201{
61243a51
DW
2202 //
2203 // Did we process the uMsg?
2204 //
2205 bool bProcessed = FALSE;
e604d44b
DW
2206 bool bAllow;
2207 MRESULT mResult;
2208 WXHICON hIcon;
2209 WXHBRUSH hBrush;
cdf1e714 2210
61243a51
DW
2211 //
2212 // For most messages we should return 0 when we do process the message
2213 //
e604d44b 2214 mResult = (MRESULT)0;
61243a51
DW
2215
2216 switch (uMsg)
cdf1e714
DW
2217 {
2218 case WM_CREATE:
2219 {
61243a51
DW
2220 bool bMayCreate;
2221
2222 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2223 ,&bMayCreate
2224 );
2225 if (bProcessed)
cdf1e714 2226 {
61243a51
DW
2227 //
2228 // Return 0 to bAllow window creation
2229 //
e604d44b 2230 mResult = (MRESULT)(bMayCreate ? 0 : -1);
cdf1e714
DW
2231 }
2232 }
2233 break;
2234
2235 case WM_DESTROY:
e604d44b
DW
2236 HandleDestroy();
2237 bProcessed = TRUE;
e604d44b 2238 break;
cdf1e714
DW
2239
2240 case WM_MOVE:
61243a51
DW
2241 bProcessed = HandleMove( LOWORD(lParam)
2242 ,HIWORD(lParam)
2243 );
cdf1e714
DW
2244 break;
2245
2246 case WM_SIZE:
61243a51
DW
2247 bProcessed = HandleSize( LOWORD(lParam)
2248 ,HIWORD(lParam)
2249 ,(WXUINT)wParam
2250 );
cdf1e714
DW
2251 break;
2252
2253 case WM_ACTIVATE:
2254 {
61243a51
DW
2255 WXWORD wState;
2256 WXHWND hWnd;
2257
2258 UnpackActivate( wParam
2259 ,lParam
2260 ,&wState
2261 ,&hWnd
2262 );
2263
2264 bProcessed = HandleActivate( wState
2265 ,(WXHWND)hWnd
2266 );
e604d44b 2267 bProcessed = FALSE;
cdf1e714
DW
2268 }
2269 break;
2270
2271 case WM_SETFOCUS:
61243a51
DW
2272 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2273 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2274 else
2275 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
cdf1e714
DW
2276 break;
2277
2278 case WM_PAINT:
61243a51 2279 bProcessed = HandlePaint();
cdf1e714
DW
2280 break;
2281
2282 case WM_CLOSE:
61243a51
DW
2283 //
2284 // Don't let the DefWindowProc() destroy our window - we'll do it
cdf1e714 2285 // ourselves in ~wxWindow
61243a51
DW
2286 //
2287 bProcessed = TRUE;
e604d44b 2288 mResult = (MRESULT)TRUE;
cdf1e714
DW
2289 break;
2290
61243a51
DW
2291 case WM_SHOW:
2292 bProcessed = HandleShow(wParam != 0, (int)lParam);
cdf1e714
DW
2293 break;
2294
61243a51
DW
2295 //
2296 // Under OS2 PM Joysticks are treated just like mouse events
2297 // The "Motion" events will be prevelent in joysticks
2298 //
cdf1e714 2299 case WM_MOUSEMOVE:
61243a51
DW
2300 case WM_BUTTON1DOWN:
2301 case WM_BUTTON1UP:
2302 case WM_BUTTON1DBLCLK:
2303 case WM_BUTTON1MOTIONEND:
2304 case WM_BUTTON1MOTIONSTART:
2305 case WM_BUTTON2DOWN:
2306 case WM_BUTTON2UP:
2307 case WM_BUTTON2DBLCLK:
2308 case WM_BUTTON2MOTIONEND:
2309 case WM_BUTTON2MOTIONSTART:
2310 case WM_BUTTON3DOWN:
2311 case WM_BUTTON3UP:
2312 case WM_BUTTON3DBLCLK:
2313 case WM_BUTTON3MOTIONEND:
2314 case WM_BUTTON3MOTIONSTART:
cdf1e714
DW
2315 {
2316 short x = LOWORD(lParam);
2317 short y = HIWORD(lParam);
2318
61243a51 2319 bProcessed = HandleMouseEvent(uMsg, x, y, (WXUINT)wParam);
cdf1e714
DW
2320 }
2321 break;
cdf1e714 2322 case WM_SYSCOMMAND:
61243a51 2323 bProcessed = HandleSysCommand(wParam, lParam);
cdf1e714
DW
2324 break;
2325
2326 case WM_COMMAND:
2327 {
2328 WORD id, cmd;
2329 WXHWND hwnd;
2330 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2331
61243a51 2332 bProcessed = HandleCommand(id, cmd, hwnd);
cdf1e714
DW
2333 }
2334 break;
2335
61243a51
DW
2336 //
2337 // For these messages we must return TRUE if process the message
2338 //
cdf1e714
DW
2339 case WM_DRAWITEM:
2340 case WM_MEASUREITEM:
2341 {
45bedfdd 2342 int nIdCtrl = (UINT)wParam;
45bedfdd 2343
61243a51 2344 if ( uMsg == WM_DRAWITEM )
cdf1e714 2345 {
45bedfdd 2346 bProcessed = OS2OnDrawItem(nIdCtrl,
cdf1e714
DW
2347 (WXDRAWITEMSTRUCT *)lParam);
2348 }
2349 else
2350 {
45bedfdd 2351 bProcessed = OS2OnMeasureItem(nIdCtrl,
cdf1e714
DW
2352 (WXMEASUREITEMSTRUCT *)lParam);
2353 }
2354
61243a51 2355 if ( bProcessed )
e604d44b 2356 mResult = (MRESULT)TRUE;
cdf1e714
DW
2357 }
2358 break;
2359
61243a51 2360 case WM_QUERYDLGCODE:
cdf1e714
DW
2361 if ( m_lDlgCode )
2362 {
e604d44b 2363 mResult = (MRESULT)m_lDlgCode;
61243a51 2364 bProcessed = TRUE;
cdf1e714 2365 }
61243a51 2366 //
cdf1e714 2367 //else: get the dlg code from the DefWindowProc()
61243a51 2368 //
cdf1e714
DW
2369 break;
2370
61243a51
DW
2371 //
2372 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2373 // and key-down events are obtained from the WM_CHAR params.
2374 //
2375 case WM_CHAR:
cdf1e714 2376 {
61243a51 2377 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 2378
61243a51
DW
2379 if (uKeyFlags & KC_KEYUP)
2380 {
2381 bProcessed = HandleKeyUp((WXDWORD)wParam, lParam);
cdf1e714 2382 break;
61243a51
DW
2383 }
2384 else // keydown event
2385 {
2386 //
2387 // If this has been processed by an event handler,
2388 // return 0 now (we've handled it). DON't RETURN
2389 // we still need to process further
2390 //
2391 HandleKeyDown((WXDWORD)wParam, lParam);
2392 if (uKeyFlags & KC_VIRTUALKEY)
cdf1e714 2393 {
61243a51
DW
2394 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2395
2396 //
2397 // We consider these message "not interesting" to OnChar
2398 //
2399 if (uVk == VK_SHIFT || uVk == VK_CTRL )
2400 {
2401 bProcessed = TRUE;
2402 break;
2403 }
2404 switch(uVk)
2405 {
2406 //
2407 // Avoid duplicate messages to OnChar for these ASCII keys: they
2408 // will be translated by TranslateMessage() and received in WM_CHAR
2409 case VK_ESC:
2410 case VK_SPACE:
2411 case VK_ENTER:
2412 case VK_BACKSPACE:
2413 case VK_TAB:
2414 // But set processed to FALSE, not TRUE to still pass them to
2415 // the control's default window proc - otherwise built-in
2416 // keyboard handling won't work
2417 bProcessed = FALSE;
2418 break;
2419
2420 case VK_LEFT:
2421 case VK_RIGHT:
2422 case VK_DOWN:
2423 case VK_UP:
2424 default:
2425 bProcessed = HandleChar((WXDWORD)wParam, lParam);
2426 }
2427 break;
cdf1e714 2428 }
61243a51
DW
2429 else // WM_CHAR -- Always an ASCII character
2430 {
2431 bProcessed = HandleChar((WXDWORD)wParam, lParam, TRUE);
2432 break;
2433 }
2434 }
cdf1e714 2435 }
cdf1e714
DW
2436
2437 case WM_HSCROLL:
2438 case WM_VSCROLL:
2439 {
61243a51
DW
2440 WXWORD wCode;
2441 WXWORD wPos;
2442 WXHWND hWnd;
2443 UnpackScroll( wParam
2444 ,lParam
2445 ,&wCode
2446 ,&wPos
2447 ,&hWnd
2448 );
2449
2450 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2451 : wxVERTICAL
2452 ,wCode
2453 ,wPos
2454 ,hWnd
2455 );
cdf1e714
DW
2456 }
2457 break;
2458
61243a51
DW
2459#if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2460 case WM_CTLCOLORCHANGE:
cdf1e714 2461 {
e604d44b 2462 bProcessed = HandleCtlColor(&hBrush);
61243a51
DW
2463 }
2464 break;
2465#endif
8d854fa9
DW
2466 case WM_ERASEBACKGROUND:
2467 //
2468 // Returning TRUE to requestw PM to paint the window background
2469 // in SYSCLR_WINDOW. We don't really want that
2470 //
2471 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2472 mResult = (MRESULT)(FALSE);
2473 break;
2474
61243a51
DW
2475 //
2476 // Instead of CTLCOLOR messages PM sends QUERYWINDOWPARAMS to
2477 // things such as colors and fonts and such
2478 //
2479 case WM_QUERYWINDOWPARAMS:
2480 {
2481 PWNDPARAMS pWndParams = (PWNDPARAMS)wParam;
2482
2483 bProcessed = HandleWindowParams( pWndParams
2484 ,lParam
2485 );
cdf1e714
DW
2486 }
2487 break;
2488
2489 // the return value for this message is ignored
2490 case WM_SYSCOLORCHANGE:
61243a51 2491 bProcessed = HandleSysColorChange();
cdf1e714
DW
2492 break;
2493
61243a51
DW
2494 case WM_REALIZEPALETTE:
2495 bProcessed = HandlePaletteChanged();
cdf1e714
DW
2496 break;
2497
61243a51
DW
2498 case WM_PRESPARAMCHANGED:
2499 bProcessed = HandlePresParamChanged(wParam);
cdf1e714
DW
2500 break;
2501
cdf1e714 2502
61243a51
DW
2503 // move all drag and drops to wxDrg
2504 case WM_ENDDRAG:
2505 bProcessed = HandleEndDrag(wParam);
cdf1e714
DW
2506 break;
2507
61243a51
DW
2508 case WM_INITDLG:
2509 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
cdf1e714 2510
61243a51 2511 if ( bProcessed )
cdf1e714
DW
2512 {
2513 // we never set focus from here
e604d44b 2514 mResult = FALSE;
cdf1e714
DW
2515 }
2516 break;
2517
61243a51
DW
2518 // wxFrame specific message
2519 case WM_MINMAXFRAME:
f6bcfd97 2520 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
cdf1e714
DW
2521 break;
2522
61243a51
DW
2523 case WM_SYSVALUECHANGED:
2524 // TODO: do something
e604d44b 2525 mResult = (MRESULT)TRUE;
cdf1e714
DW
2526 break;
2527
61243a51
DW
2528 //
2529 // Comparable to WM_SETPOINTER for windows, only for just controls
2530 //
2531 case WM_CONTROLPOINTER:
2532 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2533 ,(HWND)lParam // Cursor Handle
2534 );
2535 if (bProcessed )
cdf1e714 2536 {
61243a51
DW
2537 //
2538 // Returning TRUE stops the DefWindowProc() from further
cdf1e714
DW
2539 // processing this message - exactly what we need because we've
2540 // just set the cursor.
61243a51 2541 //
e604d44b 2542 mResult = (MRESULT)TRUE;
cdf1e714
DW
2543 }
2544 break;
2545 }
61243a51 2546 if (!bProcessed)
cdf1e714
DW
2547 {
2548#ifdef __WXDEBUG__
2549 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
61243a51 2550 wxGetMessageName(uMsg));
cdf1e714 2551#endif // __WXDEBUG__
d08f23a7
DW
2552 if (IsKindOf(CLASSINFO(wxFrame)))
2553 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
2554 else
2555 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
cdf1e714 2556 }
e604d44b 2557 return mResult;
0367c1c0 2558} // end of wxWindowOS2::OS2WindowProc
cdf1e714 2559
61243a51 2560//
cdf1e714 2561// Dialog window proc
61243a51
DW
2562//
2563MRESULT wxDlgProc(
2564 HWND hWnd
2565, UINT uMsg
2566, MPARAM wParam
2567, MPARAM lParam)
cdf1e714 2568{
61243a51 2569 if (uMsg == WM_INITDLG)
cdf1e714 2570 {
61243a51
DW
2571 //
2572 // For this message, returning TRUE tells system to set focus to the
cdf1e714 2573 // first control in the dialog box
61243a51
DW
2574 //
2575 return (MRESULT)TRUE;
cdf1e714
DW
2576 }
2577 else
2578 {
61243a51
DW
2579 //
2580 // For all the other ones, FALSE means that we didn't process the
cdf1e714 2581 // message
61243a51
DW
2582 //
2583 return (MRESULT)0;
cdf1e714 2584 }
61243a51 2585} // end of wxDlgProc
cdf1e714 2586
61243a51
DW
2587wxWindow* wxFindWinFromHandle(
2588 WXHWND hWnd
2589)
cdf1e714 2590{
61243a51
DW
2591 wxNode* pNode = wxWinHandleList->Find((long)hWnd);
2592
2593 if (!pNode)
cdf1e714 2594 return NULL;
61243a51
DW
2595 return (wxWindow *)pNode->Data();
2596} // end of wxFindWinFromHandle
cdf1e714 2597
61243a51
DW
2598void wxAssociateWinWithHandle(
2599 HWND hWnd
2600, wxWindow* pWin
2601)
cdf1e714 2602{
61243a51
DW
2603 //
2604 // Adding NULL hWnd is (first) surely a result of an error and
cdf1e714 2605 // (secondly) breaks menu command processing
61243a51 2606 //
cdf1e714
DW
2607 wxCHECK_RET( hWnd != (HWND)NULL,
2608 wxT("attempt to add a NULL hWnd to window list ignored") );
2609
2610
61243a51
DW
2611 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
2612
2613 if (pOldWin && (pOldWin != pWin))
cdf1e714 2614 {
61243a51
DW
2615 wxString str(pWin->GetClassInfo()->GetClassName());
2616 wxLogError( "Bug! Found existing HWND %X for new window of class %s"
2617 ,(int)hWnd
2618 ,(const char*)str
2619 );
cdf1e714 2620 }
61243a51 2621 else if (!pOldWin)
cdf1e714 2622 {
61243a51
DW
2623 wxWinHandleList->Append( (long)hWnd
2624 ,pWin
2625 );
cdf1e714 2626 }
61243a51 2627} // end of wxAssociateWinWithHandle
cdf1e714 2628
61243a51
DW
2629void wxRemoveHandleAssociation(
2630 wxWindow* pWin
2631)
cdf1e714 2632{
61243a51
DW
2633 wxWinHandleList->DeleteObject(pWin);
2634} // end of wxRemoveHandleAssociation
cdf1e714 2635
61243a51 2636//
cdf1e714
DW
2637// Default destroyer - override if you destroy it in some other way
2638// (e.g. with MDI child windows)
61243a51 2639//
0367c1c0 2640void wxWindowOS2::OS2DestroyWindow()
cdf1e714
DW
2641{
2642}
2643
0367c1c0 2644void wxWindowOS2::OS2DetachWindowMenu()
cdf1e714 2645{
61243a51 2646 if (m_hMenu)
cdf1e714 2647 {
61243a51 2648 HMENU hMenu = (HMENU)m_hMenu;
cdf1e714 2649
61243a51
DW
2650 int nN = (int)::WinSendMsg(hMenu, MM_QUERYITEMCOUNT, 0, 0);
2651 int i;
2652
2653 for (i = 0; i < nN; i++)
cdf1e714 2654 {
61243a51
DW
2655 wxChar zBuf[100];
2656 int nChars = (int)::WinSendMsg( hMenu
2657 ,MM_QUERYITEMTEXT
2658 ,MPFROM2SHORT(i, nN)
2659 ,zBuf
2660 );
2661 if (!nChars)
cdf1e714
DW
2662 {
2663 wxLogLastError(wxT("GetMenuString"));
cdf1e714
DW
2664 continue;
2665 }
2666
61243a51 2667 if (wxStrcmp(zBuf, wxT("&Window")) == 0)
cdf1e714 2668 {
61243a51 2669 ::WinSendMsg(hMenu, MM_DELETEITEM, MPFROM2SHORT(i, TRUE), 0);
cdf1e714
DW
2670 break;
2671 }
2672 }
2673 }
0367c1c0 2674} // end of wxWindowOS2::OS2DetachWindowMenu
cdf1e714 2675
0367c1c0 2676bool wxWindowOS2::OS2Create(
f23208ca
DW
2677 WXHWND hParent
2678, PSZ zClass
61243a51 2679, const wxChar* zTitle
61243a51 2680, WXDWORD dwStyle
f23208ca
DW
2681, long lX
2682, long lY
2683, long lWidth
2684, long lHeight
2685, WXHWND hOwner
2686, WXHWND hZOrder
2687, unsigned long ulId
2688, void* pCtlData
2689, void* pPresParams
008089f6 2690, WXDWORD dwExStyle
61243a51
DW
2691)
2692{
914589c2
DW
2693 ERRORID vError;
2694 wxString sError;
5b3ed311 2695 long lX1 = 0L;
f23208ca 2696 long lY1 = 0L;
5b3ed311
DW
2697 long lWidth1 = 20L;
2698 long lHeight1 = 20L;
f23208ca 2699 int nControlId = 0;
51c1d535
DW
2700 int nNeedsubclass = 0;
2701 PCSZ pszClass = zClass;
cdf1e714 2702
61243a51 2703 //
cdf1e714
DW
2704 // Find parent's size, if it exists, to set up a possible default
2705 // panel size the size of the parent window
61243a51
DW
2706 //
2707 RECTL vParentRect;
2708 HWND hWndClient;
2709
cb71578c
DW
2710 lX1 = lX;
2711 lY1 = lY;
f23208ca
DW
2712 if (lWidth > -1L)
2713 lWidth1 = lWidth;
2714 if (lHeight > -1L)
2715 lHeight1 = lHeight;
cdf1e714
DW
2716
2717 wxWndHook = this;
2718
f23208ca
DW
2719 //
2720 // check to see if the new window is a standard control
2721 //
2722 if ((ULONG)zClass == (ULONG)WC_BUTTON ||
2723 (ULONG)zClass == (ULONG)WC_COMBOBOX ||
2724 (ULONG)zClass == (ULONG)WC_CONTAINER ||
2725 (ULONG)zClass == (ULONG)WC_ENTRYFIELD ||
40bd6154 2726 (ULONG)zClass == (ULONG)WC_FRAME ||
f23208ca
DW
2727 (ULONG)zClass == (ULONG)WC_LISTBOX ||
2728 (ULONG)zClass == (ULONG)WC_MENU ||
2729 (ULONG)zClass == (ULONG)WC_NOTEBOOK ||
2730 (ULONG)zClass == (ULONG)WC_SCROLLBAR ||
2731 (ULONG)zClass == (ULONG)WC_SPINBUTTON ||
2732 (ULONG)zClass == (ULONG)WC_STATIC ||
2733 (ULONG)zClass == (ULONG)WC_TITLEBAR ||
2734 (ULONG)zClass == (ULONG)WC_VALUESET
2735 )
cdf1e714 2736 {
f23208ca 2737 nControlId = ulId;
cdf1e714 2738 }
51c1d535
DW
2739 else
2740 {
2741 // no standard controls
2742 if(wxString (wxT("wxFrameClass")) == wxString(zClass) )
2743 {
2744 pszClass = WC_FRAME;
2745 nNeedsubclass = 1;
2746 }
2747 else
2748 {
2749 nControlId = ulId;
2750 if(nControlId < 0)
2751 nControlId = FID_CLIENT;
2752 }
2753 }
cdf1e714 2754
f23208ca
DW
2755 //
2756 // We will either have a registered class via string name or a standard PM Class via a long
2757 //
2758 m_hWnd = (WXHWND)::WinCreateWindow( (HWND)hParent
2759 ,zClass
2760 ,(PSZ)zTitle ? zTitle : wxT("")
2761 ,(ULONG)dwStyle
2762 ,(LONG)lX1
2763 ,(LONG)lY1
2764 ,(LONG)lWidth
2765 ,(LONG)lHeight
51c1d535 2766 ,hOwner
f23208ca 2767 ,HWND_TOP
51c1d535 2768 ,(ULONG)nControlId
f23208ca
DW
2769 ,pCtlData
2770 ,pPresParams
2771 );
2772 if (!m_hWnd)
2773 {
2774 vError = ::WinGetLastError(vHabmain);
2775 sError = wxPMErrorToStr(vError);
2776 wxLogError("Can't create window of class %s!. Error: %s\n", zClass, sError);
2777 return FALSE;
cdf1e714 2778 }
008089f6 2779 m_dwExStyle = dwExStyle;
f6bcfd97 2780 ::WinSetWindowULong(m_hWnd, QWL_USER, (ULONG) this);
cdf1e714 2781 wxWndHook = NULL;
61243a51 2782
cdf1e714 2783#ifdef __WXDEBUG__
61243a51
DW
2784 wxNode* pNode = wxWinHandleList->Member(this);
2785
2786 if (pNode)
cdf1e714 2787 {
61243a51
DW
2788 HWND hWnd = (HWND)pNode->GetKeyInteger();
2789
2790 if (hWnd != (HWND)m_hWnd)
2791
cdf1e714
DW
2792 {
2793 wxLogError("A second HWND association is being added for the same window!");
2794 }
2795 }
2796#endif
61243a51
DW
2797 wxAssociateWinWithHandle((HWND)m_hWnd
2798 ,this
2799 );
cd212ee4 2800 //
e604d44b
DW
2801 // Now need to subclass window.
2802 //
51c1d535
DW
2803 if(!nNeedsubclass)
2804 {
2805 wxAssociateWinWithHandle((HWND)m_hWnd,this);
2806 }
2807 else
2808 {
2809 SubclassWin(GetHWND());
2810 }
cdf1e714 2811 return TRUE;
0367c1c0 2812} // end of wxWindowOS2::OS2Create
cdf1e714
DW
2813
2814// ===========================================================================
2815// OS2 PM message handlers
2816// ===========================================================================
2817
2818// ---------------------------------------------------------------------------
61243a51 2819// window creation/destruction
cdf1e714
DW
2820// ---------------------------------------------------------------------------
2821
0367c1c0 2822bool wxWindowOS2::HandleCreate(
61243a51
DW
2823 WXLPCREATESTRUCT vCs
2824, bool* pbMayCreate
2825)
cdf1e714 2826{
61243a51 2827 wxWindowCreateEvent vEvent(this);
cdf1e714 2828
61243a51
DW
2829 (void)GetEventHandler()->ProcessEvent(vEvent);
2830 *pbMayCreate = TRUE;
cdf1e714 2831 return TRUE;
0367c1c0 2832} // end of wxWindowOS2::HandleCreate
cdf1e714 2833
0367c1c0 2834bool wxWindowOS2::HandleDestroy()
cdf1e714 2835{
61243a51 2836 wxWindowDestroyEvent vEvent(this);
cdf1e714 2837
61243a51
DW
2838 (void)GetEventHandler()->ProcessEvent(vEvent);
2839
2840 //
2841 // Delete our drop target if we've got one
2842 //
cdf1e714 2843#if wxUSE_DRAG_AND_DROP
61243a51 2844 if (m_dropTarget != NULL)
cdf1e714 2845 {
61243a51 2846 m_dropTarget->Revoke(m_hWnd);
cdf1e714
DW
2847 delete m_dropTarget;
2848 m_dropTarget = NULL;
2849 }
2850#endif // wxUSE_DRAG_AND_DROP
2851
61243a51 2852 //
cdf1e714 2853 // WM_DESTROY handled
61243a51 2854 //
cdf1e714 2855 return TRUE;
0367c1c0 2856} // end of wxWindowOS2::HandleDestroy
cdf1e714
DW
2857
2858// ---------------------------------------------------------------------------
2859// activation/focus
2860// ---------------------------------------------------------------------------
0367c1c0 2861void wxWindowOS2::OnSetFocus(
61243a51
DW
2862 wxFocusEvent& rEvent
2863)
cdf1e714 2864{
61243a51 2865 rEvent.Skip();
0367c1c0 2866} // end of wxWindowOS2::OnSetFocus
61243a51 2867
0367c1c0 2868bool wxWindowOS2::HandleActivate(
61243a51
DW
2869 int nState
2870, WXHWND WXUNUSED(hActivate)
2871)
2872{
2873 wxActivateEvent vEvent( wxEVT_ACTIVATE
2874 ,(bool)nState
2875 ,m_windowId
2876 );
2877 vEvent.SetEventObject(this);
2878 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2879} // end of wxWindowOS2::HandleActivate
61243a51 2880
0367c1c0 2881bool wxWindowOS2::HandleSetFocus(
61243a51
DW
2882 WXHWND WXUNUSED(hWnd)
2883)
cdf1e714
DW
2884{
2885#if wxUSE_CARET
61243a51 2886 //
cdf1e714 2887 // Deal with caret
61243a51
DW
2888 //
2889 if (m_caret)
cdf1e714
DW
2890 {
2891 m_caret->OnSetFocus();
2892 }
2893#endif // wxUSE_CARET
2894
1bcfc0e1
DW
2895#if wxUSE_TEXTCTRL
2896 // If it's a wxTextCtrl don't send the event as it will be done
2897 // after the control gets to process it from EN_FOCUS handler
2898 if ( wxDynamicCastThis(wxTextCtrl) )
cdf1e714 2899 {
1bcfc0e1 2900 return FALSE;
cdf1e714 2901 }
1bcfc0e1 2902#endif // wxUSE_TEXTCTRL
cdf1e714 2903
61243a51 2904 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
cdf1e714 2905
61243a51
DW
2906 vEvent.SetEventObject(this);
2907 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2908} // end of wxWindowOS2::HandleSetFocus
cdf1e714 2909
0367c1c0 2910bool wxWindowOS2::HandleKillFocus(
61243a51
DW
2911 WXHWND WXUNUSED(hWnd)
2912)
cdf1e714
DW
2913{
2914#if wxUSE_CARET
61243a51 2915 //
cdf1e714 2916 // Deal with caret
61243a51
DW
2917 //
2918 if (m_caret)
cdf1e714
DW
2919 {
2920 m_caret->OnKillFocus();
2921 }
2922#endif // wxUSE_CARET
2923
61243a51
DW
2924 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
2925 ,m_windowId
2926 );
cdf1e714 2927
61243a51
DW
2928 vEvent.SetEventObject(this);
2929 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2930} // end of wxWindowOS2::HandleKillFocus
cdf1e714
DW
2931
2932// ---------------------------------------------------------------------------
2933// miscellaneous
2934// ---------------------------------------------------------------------------
2935
0367c1c0 2936bool wxWindowOS2::HandleShow(
61243a51
DW
2937 bool bShow
2938, int nStatus
2939)
cdf1e714 2940{
61243a51
DW
2941 wxShowEvent vEvent( GetId()
2942 ,bShow
2943 );
cdf1e714 2944
61243a51
DW
2945 vEvent.m_eventObject = this;
2946 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2947} // end of wxWindowOS2::HandleShow
cdf1e714 2948
0367c1c0 2949bool wxWindowOS2::HandleInitDialog(
61243a51
DW
2950 WXHWND WXUNUSED(hWndFocus)
2951)
cdf1e714 2952{
61243a51 2953 wxInitDialogEvent vEvent(GetId());
cdf1e714 2954
61243a51
DW
2955 vEvent.m_eventObject = this;
2956 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 2957} // end of wxWindowOS2::HandleInitDialog
cdf1e714 2958
0367c1c0 2959bool wxWindowOS2::HandleEndDrag(WXWPARAM wParam)
cdf1e714 2960{
61243a51 2961 // TODO: We'll handle drag and drop later
cdf1e714
DW
2962 return FALSE;
2963}
2964
0367c1c0 2965bool wxWindowOS2::HandleSetCursor(
61243a51
DW
2966 USHORT vId
2967, WXHWND hPointer
2968)
cdf1e714 2969{
61243a51
DW
2970 //
2971 // Under OS/2 PM this allows the pointer to be changed
2972 // as it passes over a control
2973 //
2974 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
2975 return TRUE;
0367c1c0 2976} // end of wxWindowOS2::HandleSetCursor
cdf1e714
DW
2977
2978// ---------------------------------------------------------------------------
2979// owner drawn stuff
2980// ---------------------------------------------------------------------------
0367c1c0 2981bool wxWindowOS2::OS2OnDrawItem(
61243a51
DW
2982 int vId
2983, WXDRAWITEMSTRUCT* pItemStruct
2984)
cdf1e714 2985{
402e2f7c 2986 wxDC vDc;
61243a51 2987
45bedfdd 2988#if wxUSE_OWNER_DRAWN
61243a51 2989 //
402e2f7c 2990 // Is it a menu item?
61243a51 2991 //
402e2f7c
DW
2992 if (vId == 0)
2993 {
5afb9458
DW
2994 ERRORID vError;
2995 wxString sError;
402e2f7c 2996 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
23122f8c
DW
2997 wxFrame* pFrame = (wxFrame*)this;
2998 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
402e2f7c 2999 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
23122f8c
DW
3000 wxRect vRect( pMeasureStruct->rclItem.xLeft
3001 ,pMeasureStruct->rclItem.yBottom
3002 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3003 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3004 );
402e2f7c
DW
3005 vDc.SetHDC( hDC
3006 ,FALSE
3007 );
3008 vDc.SetHPS(pMeasureStruct->hps);
5afb9458
DW
3009 //
3010 // Load the wxWindows Pallete and set to RGB mode
3011 //
3012 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3013 ,0L
3014 ,LCOLF_CONSECRGB
3015 ,0L
3016 ,(LONG)wxTheColourDatabase->m_nSize
3017 ,(PLONG)wxTheColourDatabase->m_palTable
3018 ))
3019 {
3020 vError = ::WinGetLastError(vHabmain);
3021 sError = wxPMErrorToStr(vError);
3022 wxLogError("Unable to set current color table. Error: %s\n", sError);
3023 }
3024 //
3025 // Set the color table to RGB mode
3026 //
3027 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3028 ,0L
3029 ,LCOLF_RGB
3030 ,0L
3031 ,0L
3032 ,NULL
3033 ))
3034 {
3035 vError = ::WinGetLastError(vHabmain);
3036 sError = wxPMErrorToStr(vError);
3037 wxLogError("Unable to set current color table. Error: %s\n", sError);
3038 }
cdf1e714 3039
23122f8c
DW
3040 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3041
3042
3043 int eAction = 0;
3044 int eStatus = 0;
cdf1e714 3045
402e2f7c 3046 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
23122f8c
DW
3047 {
3048 //
3049 // Entire Item needs to be redrawn (either it has reappeared from
3050 // behind another window or is being displayed for the first time
3051 //
402e2f7c 3052 eAction = wxOwnerDrawn::wxODDrawAll;
23122f8c
DW
3053
3054 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3055 {
3056 //
3057 // If it is currently selected we let the system handle it
3058 //
3059 eStatus |= wxOwnerDrawn::wxODSelected;
3060 }
3061 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3062 {
3063 //
3064 // If it is currently checked we draw our own
3065 //
3066 eStatus |= wxOwnerDrawn::wxODChecked;
3067 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3068 }
3069 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3070 {
3071 //
3072 // If it is currently disabled we let the system handle it
3073 //
3074 eStatus |= wxOwnerDrawn::wxODDisabled;
3075 }
3076 //
3077 // Don't really care about framed (indicationg focus) or NoDismiss
3078 //
3079 }
402e2f7c 3080 else
23122f8c 3081 {
5afb9458
DW
3082 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3083 {
3084 eAction = wxOwnerDrawn::wxODDrawAll;
3085 eStatus |= wxOwnerDrawn::wxODSelected;
3086 //
3087 // Keep the system from trying to highlight with its bogus colors
3088 //
3089 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3090 }
3091 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3092 {
3093 eAction = wxOwnerDrawn::wxODDrawAll;
3094 eStatus = 0;
3095 //
3096 // Keep the system from trying to highlight with its bogus colors
3097 //
3098 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3099 }
3100 else
3101 {
3102 //
3103 // For now we don't care about anything else
3104 // just ignore the entire message!
3105 //
3106 return TRUE;
3107 }
23122f8c
DW
3108 }
3109 //
3110 // Now redraw the item
3111 //
45bedfdd
DW
3112 return(pMenuItem->OnDrawItem( vDc
3113 ,vRect
23122f8c
DW
3114 ,(wxOwnerDrawn::wxODAction)eAction
3115 ,(wxOwnerDrawn::wxODStatus)eStatus
45bedfdd 3116 ));
402e2f7c
DW
3117 //
3118 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3119 // the system will do the highlight or fraeming or disabling for us,
3120 // otherwise, we'd have to do it ourselves.
61243a51 3121 //
cdf1e714
DW
3122 }
3123
402e2f7c
DW
3124 wxWindow* pItem = FindItem(vId);
3125
3126 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3127 {
3128 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3129 }
61243a51 3130#endif
402e2f7c 3131 return FALSE;
0367c1c0 3132} // end of wxWindowOS2::OS2OnDrawItem
cdf1e714 3133
0367c1c0 3134bool wxWindowOS2::OS2OnMeasureItem(
402e2f7c
DW
3135 int lId
3136, WXMEASUREITEMSTRUCT* pItemStruct
3137)
0e320a79 3138{
402e2f7c
DW
3139 //
3140 // Is it a menu item?
3141 //
45bedfdd 3142 if (lId == 65536) // I really don't like this...has to be a better indicator
cdf1e714 3143 {
4049cc1c 3144 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
45bedfdd 3145 {
4049cc1c
DW
3146 size_t nWidth;
3147 size_t nHeight;
3148 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
45bedfdd
DW
3149 wxFrame* pFrame = (wxFrame*)this;
3150 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
cdf1e714 3151
45bedfdd 3152 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
4049cc1c
DW
3153 nWidth = 0L;
3154 nHeight = 0L;
3155 if (pMenuItem->OnMeasureItem( &nWidth
3156 ,&nHeight
3157 ))
3158 {
3159 pMeasureStruct->rclItem.xRight = nWidth;
3160 pMeasureStruct->rclItem.xLeft = 0L;
3161 pMeasureStruct->rclItem.yTop = nHeight;
3162 pMeasureStruct->rclItem.yBottom = 0L;
3163 return TRUE;
3164 }
3165 return FALSE;
45bedfdd 3166 }
cdf1e714 3167 }
f15b4952 3168 wxWindow* pItem = FindItem(lId);
cdf1e714 3169
402e2f7c 3170 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
cdf1e714 3171 {
402e2f7c 3172 return ((wxControl *)pItem)->OS2OnMeasure(pItemStruct);
cdf1e714 3173 }
cdf1e714 3174 return FALSE;
0e320a79
DW
3175}
3176
cdf1e714
DW
3177// ---------------------------------------------------------------------------
3178// colours and palettes
3179// ---------------------------------------------------------------------------
849949b1 3180
0367c1c0 3181bool wxWindowOS2::HandleSysColorChange()
0e320a79 3182{
61243a51 3183 wxSysColourChangedEvent vEvent;
cdf1e714 3184
61243a51
DW
3185 vEvent.SetEventObject(this);
3186 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3187} // end of wxWindowOS2::HandleSysColorChange
0e320a79 3188
0367c1c0 3189bool wxWindowOS2::HandleCtlColor(
61243a51
DW
3190 WXHBRUSH* phBrush
3191)
0e320a79 3192{
61243a51
DW
3193 //
3194 // Not much provided with message. So not sure I can do anything with it
3195 //
3196 return TRUE;
0367c1c0 3197} // end of wxWindowOS2::HandleCtlColor
cdf1e714 3198
0367c1c0 3199bool wxWindowOS2::HandleWindowParams(
61243a51
DW
3200 PWNDPARAMS pWndParams
3201, WXLPARAM lParam
3202)
3203{
3204// TODO: I'll do something here, just not sure what yet
3205 return TRUE;
0e320a79
DW
3206}
3207
cdf1e714 3208// Define for each class of dialog and control
0367c1c0 3209WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC hDC,
cdf1e714
DW
3210 WXHWND hWnd,
3211 WXUINT nCtlColor,
3212 WXUINT message,
3213 WXWPARAM wParam,
3214 WXLPARAM lParam)
0e320a79 3215{
cdf1e714 3216 return (WXHBRUSH)0;
0e320a79
DW
3217}
3218
0367c1c0 3219bool wxWindowOS2::HandlePaletteChanged()
0e320a79 3220{
61243a51
DW
3221 // need to set this to something first
3222 WXHWND hWndPalChange = NULLHANDLE;
cdf1e714 3223
61243a51
DW
3224 wxPaletteChangedEvent vEvent(GetId());
3225
3226 vEvent.SetEventObject(this);
3227 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
0e320a79 3228
61243a51 3229 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3230} // end of wxWindowOS2::HandlePaletteChanged
61243a51 3231
0367c1c0 3232bool wxWindowOS2::HandlePresParamChanged(
61243a51
DW
3233 WXWPARAM wParam
3234)
0e320a79 3235{
61243a51
DW
3236 //
3237 // TODO: Once again I'll do something here when I need it
3238 //
3239 //wxQueryNewPaletteEvent event(GetId());
3240 //event.SetEventObject(this);
3241 // if the background is erased
3242// bProcessed = HandleEraseBkgnd((WXHDC)(HDC)wParam);
cdf1e714 3243
61243a51 3244 return FALSE; //GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized();
0e320a79
DW
3245}
3246
61243a51 3247//
cdf1e714 3248// Responds to colour changes: passes event on to children.
61243a51 3249//
0367c1c0 3250void wxWindowOS2::OnSysColourChanged(
61243a51
DW
3251 wxSysColourChangedEvent& rEvent
3252)
0e320a79 3253{
61243a51
DW
3254 wxNode* pNode = GetChildren().First();
3255
3256 while (pNode)
cdf1e714 3257 {
61243a51 3258 //
cdf1e714 3259 // Only propagate to non-top-level windows
61243a51
DW
3260 //
3261 wxWindow* pWin = (wxWindow *)pNode->Data();
3262
3263 if (pWin->GetParent())
cdf1e714 3264 {
61243a51 3265 wxSysColourChangedEvent vEvent;
cdf1e714 3266
61243a51
DW
3267 rEvent.m_eventObject = pWin;
3268 pWin->GetEventHandler()->ProcessEvent(vEvent);
3269 }
3270 pNode = pNode->Next();
cdf1e714 3271 }
0367c1c0 3272} // end of wxWindowOS2::OnSysColourChanged
0e320a79 3273
cdf1e714
DW
3274// ---------------------------------------------------------------------------
3275// painting
3276// ---------------------------------------------------------------------------
3277
0367c1c0 3278bool wxWindowOS2::HandlePaint()
0e320a79 3279{
61243a51 3280 HRGN hRgn = NULLHANDLE;
40bd6154
DW
3281 wxPaintEvent vEvent;
3282 HPS hPS;
3283 RECTL vRect;
61243a51
DW
3284
3285 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_NULL)
3286 {
3287 wxLogLastError("CreateRectRgn");
3288 return FALSE;
3289 }
7e99520b 3290
61243a51 3291 m_updateRegion = wxRegion(hRgn);
61243a51 3292 vEvent.SetEventObject(this);
fb83aca5
DW
3293 if (!GetEventHandler()->ProcessEvent(vEvent))
3294 {
3295 HPS hPS;
3296
3297 hPS = ::WinBeginPaint( GetHwnd()
3298 ,NULLHANDLE
3299 ,&vRect
3300 );
3301 if(hPS)
3302 {
3303 ::GpiCreateLogColorTable( hPS
3304 ,0L
3305 ,LCOLF_CONSECRGB
3306 ,0L
3307 ,(LONG)wxTheColourDatabase->m_nSize
3308 ,(PLONG)wxTheColourDatabase->m_palTable
3309 );
3310 ::GpiCreateLogColorTable( hPS
3311 ,0L
3312 ,LCOLF_RGB
3313 ,0L
3314 ,0L
3315 ,NULL
3316 );
3317
3318 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
008089f6
DW
3319
3320 if (m_dwExStyle)
3321 {
3322 LINEBUNDLE vLineBundle;
3323
3324 vLineBundle.lColor = 0x00000000; // Black
3325 vLineBundle.usMixMode = FM_OVERPAINT;
3326 vLineBundle.fxWidth = 1;
3327 vLineBundle.lGeomWidth = 1;
3328 vLineBundle.usType = LINETYPE_SOLID;
3329 vLineBundle.usEnd = 0;
3330 vLineBundle.usJoin = 0;
3331 ::GpiSetAttrs( hPS
3332 ,PRIM_LINE
3333 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
3334 ,0L
3335 ,&vLineBundle
3336 );
ad7f3189 3337 ::WinQueryWindowRect(GetHwnd(), &vRect);
008089f6
DW
3338 wxDrawBorder( hPS
3339 ,vRect
3340 ,m_dwExStyle
3341 );
3342 }
fb83aca5
DW
3343 ::WinEndPaint(hPS);
3344 }
3345 }
61243a51 3346 return (GetEventHandler()->ProcessEvent(vEvent));
0367c1c0 3347} // end of wxWindowOS2::HandlePaint
0e320a79 3348
0367c1c0 3349bool wxWindowOS2::HandleEraseBkgnd(
8d854fa9
DW
3350 WXHDC hDC
3351)
0e320a79 3352{
8d854fa9
DW
3353 SWP vSwp;
3354
3355 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3356 if (vSwp.fl & SWP_MINIMIZE)
61243a51 3357 return TRUE;
cdf1e714 3358
8d854fa9
DW
3359 wxDC vDC;
3360
3361 vDC.m_hPS = (HPS)hDC; // this is really a PS
3362 vDC.SetWindow(this);
3363 vDC.BeginDrawing();
cdf1e714 3364
8d854fa9
DW
3365 wxEraseEvent vEvent(m_windowId, &vDC);
3366
3367 vEvent.SetEventObject(this);
cdf1e714 3368
8d854fa9 3369 bool rc = GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3370
8d854fa9
DW
3371 vDC.EndDrawing();
3372 vDC.m_hPS = NULLHANDLE;
61243a51 3373 return TRUE;
0367c1c0 3374} // end of wxWindowOS2::HandleEraseBkgnd
cdf1e714 3375
0367c1c0 3376void wxWindowOS2::OnEraseBackground(
61243a51
DW
3377 wxEraseEvent& rEvent
3378)
0e320a79 3379{
8d854fa9
DW
3380 RECTL vRect;
3381 HPS hPS = rEvent.m_dc->m_hPS;
3382
3383 ::WinQueryWindowRect(GetHwnd(), &vRect);
3384 ::WinFillRect(hPS, &vRect, m_backgroundColour.GetPixel());
0367c1c0 3385} // end of wxWindowOS2::OnEraseBackground
0e320a79 3386
cdf1e714
DW
3387// ---------------------------------------------------------------------------
3388// moving and resizing
3389// ---------------------------------------------------------------------------
0e320a79 3390
0367c1c0 3391bool wxWindowOS2::HandleMinimize()
0e320a79 3392{
61243a51 3393 wxIconizeEvent vEvent(m_windowId);
cdf1e714 3394
61243a51
DW
3395 vEvent.SetEventObject(this);
3396 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3397} // end of wxWindowOS2::HandleMinimize
0e320a79 3398
0367c1c0 3399bool wxWindowOS2::HandleMaximize()
0e320a79 3400{
61243a51 3401 wxMaximizeEvent vEvent(m_windowId);
cdf1e714 3402
61243a51
DW
3403 vEvent.SetEventObject(this);
3404 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3405} // end of wxWindowOS2::HandleMaximize
0e320a79 3406
0367c1c0 3407bool wxWindowOS2::HandleMove(
61243a51
DW
3408 int nX
3409, int nY
3410)
0e320a79 3411{
61243a51
DW
3412 wxMoveEvent vEvent( wxPoint( nX
3413 ,nY
3414 )
3415 ,m_windowId
3416 );
cdf1e714 3417
61243a51
DW
3418 vEvent.SetEventObject(this);
3419 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3420} // end of wxWindowOS2::HandleMove
0e320a79 3421
0367c1c0 3422bool wxWindowOS2::HandleSize(
61243a51
DW
3423 int nWidth
3424, int nHeight
3425, WXUINT WXUNUSED(nFlag)
3426)
0e320a79 3427{
61243a51
DW
3428 wxSizeEvent vEvent( wxSize( nWidth
3429 ,nHeight
3430 )
3431 ,m_windowId
3432 );
cdf1e714 3433
61243a51
DW
3434 vEvent.SetEventObject(this);
3435 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3436} // end of wxWindowOS2::HandleSize
0e320a79 3437
0367c1c0 3438bool wxWindowOS2::HandleGetMinMaxInfo(
61243a51
DW
3439 PSWP pSwp
3440)
0e320a79 3441{
61243a51
DW
3442 bool bRc = FALSE;
3443 POINTL vPoint;
cdf1e714 3444
61243a51 3445 switch(pSwp->fl)
cdf1e714 3446 {
61243a51
DW
3447 case SWP_MAXIMIZE:
3448 ::WinGetMaxPosition(GetHwnd(), pSwp);
3449 m_maxWidth = pSwp->cx;
3450 m_maxHeight = pSwp->cy;
3451 break;
cdf1e714 3452
61243a51
DW
3453 case SWP_MINIMIZE:
3454 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3455 m_minWidth = pSwp->cx;
3456 m_minHeight = pSwp->cy;
3457 break;
cdf1e714 3458
61243a51
DW
3459 default:
3460 return FALSE;
cdf1e714 3461 }
61243a51 3462 return TRUE;
0367c1c0 3463} // end of wxWindowOS2::HandleGetMinMaxInfo
0e320a79 3464
cdf1e714
DW
3465// ---------------------------------------------------------------------------
3466// command messages
3467// ---------------------------------------------------------------------------
0367c1c0 3468bool wxWindowOS2::HandleCommand(
61243a51
DW
3469 WXWORD wId
3470, WXWORD wCmd
3471, WXHWND hControl
3472)
0e320a79 3473{
61243a51 3474 if (wxCurrentPopupMenu)
0e320a79 3475 {
61243a51 3476 wxMenu* pPopupMenu = wxCurrentPopupMenu;
0e320a79 3477
61243a51
DW
3478 wxCurrentPopupMenu = NULL;
3479 return pPopupMenu->OS2Command(wCmd, wId);
cdf1e714 3480 }
0e320a79 3481
61243a51
DW
3482 wxWindow* pWin = FindItem(wId);
3483
3484 if (!pWin)
cdf1e714 3485 {
61243a51 3486 pWin = wxFindWinFromHandle(hControl);
0e320a79 3487 }
cdf1e714 3488
61243a51
DW
3489 if (pWin)
3490 return pWin->OS2Command( wCmd
3491 ,wId
3492 );
cdf1e714 3493 return FALSE;
0367c1c0 3494} // end of wxWindowOS2::HandleCommand
de44a9f0 3495
0367c1c0 3496bool wxWindowOS2::HandleSysCommand(
61243a51
DW
3497 WXWPARAM wParam
3498, WXLPARAM lParam
3499)
0e320a79 3500{
61243a51
DW
3501 //
3502 // 4 bits are reserved
3503 //
3504 switch (SHORT1FROMMP(wParam))
3505 {
3506 case SC_MAXIMIZE:
3507 return HandleMaximize();
3508
3509 case SC_MINIMIZE:
3510 return HandleMinimize();
3511 }
cdf1e714 3512 return FALSE;
0367c1c0 3513} // end of wxWindowOS2::HandleSysCommand
cdf1e714
DW
3514
3515// ---------------------------------------------------------------------------
3516// mouse events
3517// ---------------------------------------------------------------------------
3518
0367c1c0 3519void wxWindowOS2::InitMouseEvent(
61243a51
DW
3520 wxMouseEvent& rEvent
3521, int nX
3522, int nY
3523, WXUINT uFlags
3524)
cdf1e714 3525{
61243a51
DW
3526 rEvent.m_x = nX;
3527 rEvent.m_y = nY;
3528 rEvent.m_shiftDown = ((uFlags & VK_SHIFT) != 0);
3529 rEvent.m_controlDown = ((uFlags & VK_CTRL) != 0);
3530 rEvent.m_leftDown = ((uFlags & VK_BUTTON1) != 0);
3531 rEvent.m_middleDown = ((uFlags & VK_BUTTON3) != 0);
3532 rEvent.m_rightDown = ((uFlags & VK_BUTTON2) != 0);
3533 rEvent.SetTimestamp(s_currentMsg.time);
3534 rEvent.m_eventObject = this;
cdf1e714
DW
3535
3536#if wxUSE_MOUSEEVENT_HACK
61243a51
DW
3537 m_lastMouseX = nX;
3538 m_lastMouseY = nY;
3539 m_lastMouseEvent = rEvent.GetEventType();
cdf1e714 3540#endif // wxUSE_MOUSEEVENT_HACK
0367c1c0 3541} // end of wxWindowOS2::InitMouseEvent
0e320a79 3542
0367c1c0 3543bool wxWindowOS2::HandleMouseEvent(
61243a51
DW
3544 WXUINT uMsg
3545, int nX
3546, int nY
3547, WXUINT uFlags
3548)
0e320a79 3549{
61243a51
DW
3550 //
3551 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
cdf1e714
DW
3552 // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
3553 // from the message id and take the value in the table to get wxWin event
3554 // id
61243a51 3555 //
cdf1e714
DW
3556 static const wxEventType eventsMouse[] =
3557 {
3558 wxEVT_MOTION,
3559 wxEVT_LEFT_DOWN,
3560 wxEVT_LEFT_UP,
3561 wxEVT_LEFT_DCLICK,
3562 wxEVT_RIGHT_DOWN,
3563 wxEVT_RIGHT_UP,
3564 wxEVT_RIGHT_DCLICK,
3565 wxEVT_MIDDLE_DOWN,
3566 wxEVT_MIDDLE_UP,
3567 wxEVT_MIDDLE_DCLICK
3568 };
3569
61243a51 3570 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
cdf1e714 3571
61243a51
DW
3572 InitMouseEvent( vEvent
3573 ,nX
3574 ,nY
3575 ,uFlags
3576 );
0e320a79 3577
61243a51 3578 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3579} // end of wxWindowOS2::HandleMouseEvent
61243a51 3580
0367c1c0 3581bool wxWindowOS2::HandleMouseMove(
61243a51
DW
3582 int nX
3583, int nY
3584, WXUINT uFlags
3585)
0e320a79 3586{
61243a51 3587 if (!m_bMouseInWindow)
cdf1e714 3588 {
61243a51 3589 //
cdf1e714 3590 // Generate an ENTER event
61243a51 3591 //
776d87d5 3592 m_bMouseInWindow = TRUE;
cdf1e714 3593
61243a51 3594 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
cdf1e714 3595
61243a51
DW
3596 InitMouseEvent( vEvent
3597 ,nX
3598 ,nY
3599 ,uFlags
3600 );
cdf1e714 3601
61243a51 3602 (void)GetEventHandler()->ProcessEvent(vEvent);
cdf1e714 3603 }
61243a51
DW
3604 return HandleMouseEvent( WM_MOUSEMOVE
3605 ,nX
3606 ,nY
3607 ,uFlags
3608 );
0367c1c0 3609} // end of wxWindowOS2::HandleMouseMove
0e320a79 3610
cdf1e714
DW
3611// ---------------------------------------------------------------------------
3612// keyboard handling
3613// ---------------------------------------------------------------------------
3614
61243a51
DW
3615//
3616// Create the key event of the given type for the given key - used by
3617// HandleChar and HandleKeyDown/Up
3618//
0367c1c0 3619wxKeyEvent wxWindowOS2::CreateKeyEvent(
61243a51
DW
3620 wxEventType eType
3621, int nId
3622, WXLPARAM lParam
3623) const
3624{
3625 wxKeyEvent vEvent(eType);
3626
3627 vEvent.SetId(GetId());
3628 vEvent.m_shiftDown = IsShiftDown();
3629 vEvent.m_controlDown = IsCtrlDown();
3630 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
3631
3632 vEvent.m_eventObject = (wxWindow *)this; // const_cast
3633 vEvent.m_keyCode = nId;
3634 vEvent.SetTimestamp(s_currentMsg.time);
3635
3636 //
3637 // Translate the position to client coords
3638 //
3639 POINTL vPoint;
3640 RECTL vRect;
3641
3642 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
3643 ::WinQueryWindowRect( GetHwnd()
3644 ,&vRect
3645 );
3646
3647 vPoint.x -= vRect.xLeft;
3648 vPoint.y -= vRect.yBottom;
3649
3650 vEvent.m_x = vPoint.x;
3651 vEvent.m_y = vPoint.y;
3652
3653 return vEvent;
0367c1c0 3654} // end of wxWindowOS2::CreateKeyEvent
61243a51
DW
3655
3656//
cdf1e714
DW
3657// isASCII is TRUE only when we're called from WM_CHAR handler and not from
3658// WM_KEYDOWN one
61243a51 3659//
0367c1c0 3660bool wxWindowOS2::HandleChar(
61243a51
DW
3661 WXWORD wParam
3662, WXLPARAM lParam
3663, bool isASCII
3664)
86de7616 3665{
61243a51
DW
3666 bool bCtrlDown = FALSE;
3667 int vId;
3668
3669 if (isASCII)
3670 {
3671 //
3672 // If 1 -> 26, translate to CTRL plus a letter.
3673 //
3674 vId = wParam;
3675 if ((vId > 0) && (vId < 27))
3676 {
3677 switch (vId)
3678 {
3679 case 13:
3680 vId = WXK_RETURN;
3681 break;
3682
3683 case 8:
3684 vId = WXK_BACK;
3685 break;
3686
3687 case 9:
3688 vId = WXK_TAB;
3689 break;
3690
3691 default:
3692 bCtrlDown = TRUE;
3693 vId = vId + 96;
3694 }
3695 }
3696 }
3697 else if ( (vId = wxCharCodeOS2ToWX(wParam)) == 0)
3698 {
3699 //
3700 // It's ASCII and will be processed here only when called from
3701 // WM_CHAR (i.e. when isASCII = TRUE), don't process it now
3702 //
3703 vId = -1;
3704 }
3705
3706 if (vId != -1)
3707 {
3708 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
3709 ,vId
3710 ,lParam
3711 ));
3712
3713 if (bCtrlDown)
3714 {
3715 vEvent.m_controlDown = TRUE;
3716 }
3717
3718 if (GetEventHandler()->ProcessEvent(vEvent))
3719 return TRUE;
3720 }
3721 return FALSE;
cdf1e714 3722}
86de7616 3723
0367c1c0 3724bool wxWindowOS2::HandleKeyDown(
61243a51
DW
3725 WXWORD wParam
3726, WXLPARAM lParam
3727)
cdf1e714 3728{
61243a51 3729 int nId = wxCharCodeOS2ToWX(wParam);
86de7616 3730
61243a51
DW
3731 if (!nId)
3732 {
3733 //
3734 // Normal ASCII char
3735 //
3736 nId = wParam;
3737 }
3738
3739 if (nId != -1)
3740 {
3741 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
3742 ,nId
3743 ,lParam
3744 ));
3745
3746 if (GetEventHandler()->ProcessEvent(vEvent))
3747 {
3748 return TRUE;
3749 }
3750 }
3751 return FALSE;
0367c1c0 3752} // end of wxWindowOS2::HandleKeyDown
61243a51 3753
0367c1c0 3754bool wxWindowOS2::HandleKeyUp(
61243a51
DW
3755 WXWORD wParam
3756, WXLPARAM lParam
3757)
86de7616 3758{
61243a51
DW
3759 int nId = wxCharCodeOS2ToWX(wParam);
3760
3761 if (!nId)
3762 {
3763 //
3764 // Normal ASCII char
3765 //
3766 nId = wParam;
3767 }
3768
3769 if (nId != -1)
3770 {
3771 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
3772 ,nId
3773 ,lParam
3774 ));
3775
3776 if (GetEventHandler()->ProcessEvent(vEvent))
3777 return TRUE;
3778 }
3779 return FALSE;
0367c1c0 3780} // end of wxWindowOS2::HandleKeyUp
86de7616 3781
cdf1e714
DW
3782// ---------------------------------------------------------------------------
3783// joystick
3784// ---------------------------------------------------------------------------
86de7616 3785
cdf1e714
DW
3786// ---------------------------------------------------------------------------
3787// scrolling
3788// ---------------------------------------------------------------------------
3789
0367c1c0 3790bool wxWindowOS2::OS2OnScroll(
61243a51
DW
3791 int nOrientation
3792, WXWORD wParam
3793, WXWORD wPos
3794, WXHWND hControl
3795)
cdf1e714 3796{
61243a51 3797 if (hControl)
86de7616 3798 {
61243a51
DW
3799 wxWindow* pChild = wxFindWinFromHandle(hControl);
3800
3801 if (pChild )
3802 return pChild->OS2OnScroll( nOrientation
3803 ,wParam
3804 ,wPos
3805 ,hControl
3806 );
cdf1e714 3807 }
86de7616 3808
61243a51
DW
3809 wxScrollWinEvent vEvent;
3810
3811 vEvent.SetPosition(wPos);
3812 vEvent.SetOrientation(nOrientation);
3813 vEvent.m_eventObject = this;
3814
3815 switch (wParam)
3816 {
3817 case SB_LINEUP:
3818 vEvent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
3819 break;
3820
3821 case SB_LINEDOWN:
3822 vEvent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
3823 break;
3824
3825 case SB_PAGEUP:
3826 vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
3827 break;
3828
3829 case SB_PAGEDOWN:
3830 vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
3831 break;
3832
3833 case SB_SLIDERPOSITION:
3834 vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
3835 break;
3836
3837 case SB_SLIDERTRACK:
3838 vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
3839 break;
3840
3841 default:
3842 return FALSE;
3843 }
3844 return GetEventHandler()->ProcessEvent(vEvent);
0367c1c0 3845} // end of wxWindowOS2::OS2OnScroll
86de7616 3846
cdf1e714
DW
3847// ===========================================================================
3848// global functions
3849// ===========================================================================
3850
61243a51
DW
3851void wxGetCharSize(
3852 WXHWND hWnd
3853, int* pX
3854, int* pY
3855,wxFont* pTheFont
3856)
cdf1e714 3857{
61243a51
DW
3858 // TODO: we'll do this later
3859} // end of wxGetCharSize
cdf1e714 3860
61243a51 3861//
cdf1e714
DW
3862// Returns 0 if was a normal ASCII value, not a special key. This indicates that
3863// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
61243a51
DW
3864//
3865int wxCharCodeOS2ToWX(
3866 int nKeySym
3867)
cdf1e714 3868{
61243a51
DW
3869 int nId = 0;
3870
3871 switch (nKeySym)
3872 {
3873 case VK_BACKTAB: nId = WXK_BACK; break;
3874 case VK_TAB: nId = WXK_TAB; break;
3875 case VK_CLEAR: nId = WXK_CLEAR; break;
3876 case VK_ENTER: nId = WXK_RETURN; break;
3877 case VK_SHIFT: nId = WXK_SHIFT; break;
3878 case VK_CTRL: nId = WXK_CONTROL; break;
3879 case VK_PAUSE: nId = WXK_PAUSE; break;
3880 case VK_SPACE: nId = WXK_SPACE; break;
3881 case VK_ESC: nId = WXK_ESCAPE; break;
3882 case VK_END: nId = WXK_END; break;
3883 case VK_HOME : nId = WXK_HOME; break;
3884 case VK_LEFT : nId = WXK_LEFT; break;
3885 case VK_UP: nId = WXK_UP; break;
3886 case VK_RIGHT: nId = WXK_RIGHT; break;
3887 case VK_DOWN : nId = WXK_DOWN; break;
3888 case VK_PRINTSCRN: nId = WXK_PRINT; break;
3889 case VK_INSERT: nId = WXK_INSERT; break;
3890 case VK_DELETE: nId = WXK_DELETE; break;
3891 case VK_F1: nId = WXK_F1; break;
3892 case VK_F2: nId = WXK_F2; break;
3893 case VK_F3: nId = WXK_F3; break;
3894 case VK_F4: nId = WXK_F4; break;
3895 case VK_F5: nId = WXK_F5; break;
3896 case VK_F6: nId = WXK_F6; break;
3897 case VK_F7: nId = WXK_F7; break;
3898 case VK_F8: nId = WXK_F8; break;
3899 case VK_F9: nId = WXK_F9; break;
3900 case VK_F10: nId = WXK_F10; break;
3901 case VK_F11: nId = WXK_F11; break;
3902 case VK_F12: nId = WXK_F12; break;
3903 case VK_F13: nId = WXK_F13; break;
3904 case VK_F14: nId = WXK_F14; break;
3905 case VK_F15: nId = WXK_F15; break;
3906 case VK_F16: nId = WXK_F16; break;
3907 case VK_F17: nId = WXK_F17; break;
3908 case VK_F18: nId = WXK_F18; break;
3909 case VK_F19: nId = WXK_F19; break;
3910 case VK_F20: nId = WXK_F20; break;
3911 case VK_F21: nId = WXK_F21; break;
3912 case VK_F22: nId = WXK_F22; break;
3913 case VK_F23: nId = WXK_F23; break;
3914 case VK_F24: nId = WXK_F24; break;
3915 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
3916 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
3917 default:
86de7616 3918 {
cdf1e714 3919 return 0;
86de7616
DW
3920 }
3921 }
61243a51
DW
3922 return nId;
3923} // end of wxCharCodeOS2ToWX
86de7616 3924
61243a51
DW
3925int wxCharCodeWXToOS2(
3926 int nId
3927, bool* bIsVirtual
3928)
86de7616 3929{
61243a51
DW
3930 int nKeySym = 0;
3931
3932 *bIsVirtual = TRUE;
3933 switch (nId)
3934 {
3935 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
3936 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
3937 case WXK_CONTROL: nKeySym = VK_CTRL; break;
3938 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
3939 case WXK_END: nKeySym = VK_END; break;
3940 case WXK_HOME : nKeySym = VK_HOME; break;
3941 case WXK_LEFT : nKeySym = VK_LEFT; break;
3942 case WXK_UP: nKeySym = VK_UP; break;
3943 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
3944 case WXK_DOWN : nKeySym = VK_DOWN; break;
3945 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
3946 case WXK_INSERT: nKeySym = VK_INSERT; break;
3947 case WXK_DELETE: nKeySym = VK_DELETE; break;
3948 case WXK_F1: nKeySym = VK_F1; break;
3949 case WXK_F2: nKeySym = VK_F2; break;
3950 case WXK_F3: nKeySym = VK_F3; break;
3951 case WXK_F4: nKeySym = VK_F4; break;
3952 case WXK_F5: nKeySym = VK_F5; break;
3953 case WXK_F6: nKeySym = VK_F6; break;
3954 case WXK_F7: nKeySym = VK_F7; break;
3955 case WXK_F8: nKeySym = VK_F8; break;
3956 case WXK_F9: nKeySym = VK_F9; break;
3957 case WXK_F10: nKeySym = VK_F10; break;
3958 case WXK_F11: nKeySym = VK_F11; break;
3959 case WXK_F12: nKeySym = VK_F12; break;
3960 case WXK_F13: nKeySym = VK_F13; break;
3961 case WXK_F14: nKeySym = VK_F14; break;
3962 case WXK_F15: nKeySym = VK_F15; break;
3963 case WXK_F16: nKeySym = VK_F16; break;
3964 case WXK_F17: nKeySym = VK_F17; break;
3965 case WXK_F18: nKeySym = VK_F18; break;
3966 case WXK_F19: nKeySym = VK_F19; break;
3967 case WXK_F20: nKeySym = VK_F20; break;
3968 case WXK_F21: nKeySym = VK_F21; break;
3969 case WXK_F22: nKeySym = VK_F22; break;
3970 case WXK_F23: nKeySym = VK_F23; break;
3971 case WXK_F24: nKeySym = VK_F24; break;
3972 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
3973 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
3974 default:
cdf1e714 3975 {
61243a51
DW
3976 *bIsVirtual = FALSE;
3977 nKeySym = nId;
cdf1e714
DW
3978 break;
3979 }
86de7616 3980 }
61243a51
DW
3981 return nKeySym;
3982} // end of wxCharCodeWXToOS2
86de7616 3983
61243a51 3984wxWindow* wxGetActiveWindow()
cdf1e714 3985{
61243a51 3986 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
86de7616 3987
61243a51
DW
3988 if (hWnd != 0)
3989 {
3990 return wxFindWinFromHandle((WXHWND)hWnd);
3991 }
3992 return NULL;
3993} // end of wxGetActiveWindow
cdf1e714
DW
3994
3995#ifdef __WXDEBUG__
61243a51
DW
3996const char* wxGetMessageName(
3997 int nMessage)
cdf1e714 3998{
61243a51 3999 switch (nMessage)
86de7616 4000 {
cdf1e714
DW
4001 case 0x0000: return "WM_NULL";
4002 case 0x0001: return "WM_CREATE";
4003 case 0x0002: return "WM_DESTROY";
61243a51
DW
4004 case 0x0004: return "WM_ENABLE";
4005 case 0x0005: return "WM_SHOW";
4006 case 0x0006: return "WM_MOVE";
4007 case 0x0007: return "WM_SIZE";
4008 case 0x0008: return "WM_ADJUSTWINDOWPOS";
4009 case 0x0009: return "WM_CALCVALIDRECTS";
4010 case 0x000A: return "WM_SETWINDOWPARAMS";
4011 case 0x000B: return "WM_QUERYWINDOWPARAMS";
4012 case 0x000C: return "WM_HITTEST";
4013 case 0x000D: return "WM_ACTIVATE";
4014 case 0x000F: return "WM_SETFOCUS";
4015 case 0x0010: return "WM_SETSELECTION";
4016 case 0x0011: return "WM_PPAINT";
4017 case 0x0012: return "WM_PSETFOCUS";
4018 case 0x0013: return "WM_PSYSCOLORCHANGE";
4019 case 0x0014: return "WM_PSIZE";
4020 case 0x0015: return "WM_PACTIVATE";
4021 case 0x0016: return "WM_PCONTROL";
4022 case 0x0020: return "WM_COMMAND";
4023 case 0x0021: return "WM_SYSCOMMAND";
4024 case 0x0022: return "WM_HELP";
4025 case 0x0023: return "WM_PAINT";
4026 case 0x0024: return "WM_TIMER";
4027 case 0x0025: return "WM_SEM1";
4028 case 0x0026: return "WM_SEM2";
4029 case 0x0027: return "WM_SEM3";
4030 case 0x0028: return "WM_SEM4";
4031 case 0x0029: return "WM_CLOSE";
4032 case 0x002A: return "WM_QUIT";
4033 case 0x002B: return "WM_SYSCOLORCHANGE";
4034 case 0x002D: return "WM_SYSVALUECHANGE";
4035 case 0x002E: return "WM_APPTERMINATENOTIFY";
4036 case 0x002F: return "WM_PRESPARAMCHANGED";
4037 // Control notification messages
4038 case 0x0030: return "WM_CONTROL";
4039 case 0x0031: return "WM_VSCROLL";
4040 case 0x0032: return "WM_HSCROLL";
4041 case 0x0033: return "WM_INITMENU";
4042 case 0x0034: return "WM_MENUSELECT";
4043 case 0x0035: return "WM_MENUSEND";
4044 case 0x0036: return "WM_DRAWITEM";
4045 case 0x0037: return "WM_MEASUREITEM";
4046 case 0x0038: return "WM_CONTROLPOINTER";
4047 case 0x003A: return "WM_QUERYDLGCODE";
4048 case 0x003B: return "WM_INITDLG";
4049 case 0x003C: return "WM_SUBSTITUTESTRING";
4050 case 0x003D: return "WM_MATCHMNEMONIC";
4051 case 0x003E: return "WM_SAVEAPPLICATION";
4052 case 0x0129: return "WM_CTLCOLORCHANGE";
4053 case 0x0130: return "WM_QUERYCTLTYPE";
4054 // Frame messages
4055 case 0x0040: return "WM_FLASHWINDOW";
4056 case 0x0041: return "WM_FORMATFRAME";
4057 case 0x0042: return "WM_UPDATEFRAME";
4058 case 0x0043: return "WM_FOCUSCHANGE";
4059 case 0x0044: return "WM_SETBORDERSIZE";
4060 case 0x0045: return "WM_TRACKFRAME";
4061 case 0x0046: return "WM_MINMAXFRAME";
4062 case 0x0047: return "WM_SETICON";
4063 case 0x0048: return "WM_QUERYICON";
4064 case 0x0049: return "WM_SETACCELTABLE";
4065 case 0x004A: return "WM_QUERYACCELTABLE";
4066 case 0x004B: return "WM_TRANSLATEACCEL";
4067 case 0x004C: return "WM_QUERYTRACKINFO";
4068 case 0x004D: return "WM_QUERYBORDERSIZE";
4069 case 0x004E: return "WM_NEXTMENU";
4070 case 0x004F: return "WM_ERASEBACKGROUND";
4071 case 0x0050: return "WM_QUERYFRAMEINFO";
4072 case 0x0051: return "WM_QUERYFOCUSCHAIN";
4073 case 0x0052: return "WM_OWNERPOSCHANGE";
4074 case 0x0053: return "WM_CACLFRAMERECT";
4075 case 0x0055: return "WM_WINDOWPOSCHANGED";
4076 case 0x0056: return "WM_ADJUSTFRAMEPOS";
4077 case 0x0059: return "WM_QUERYFRAMECTLCOUNT";
4078 case 0x005B: return "WM_QUERYHELPINFO";
4079 case 0x005C: return "WM_SETHELPINFO";
4080 case 0x005D: return "WM_ERROR";
4081 case 0x005E: return "WM_REALIZEPALETTE";
4082 // Clipboard messages
4083 case 0x0060: return "WM_RENDERFMT";
4084 case 0x0061: return "WM_RENDERALLFMTS";
4085 case 0x0062: return "WM_DESTROYCLIPBOARD";
4086 case 0x0063: return "WM_PAINTCLIPBOARD";
4087 case 0x0064: return "WM_SIZECLIPBOARD";
4088 case 0x0065: return "WM_HSCROLLCLIPBOARD";
4089 case 0x0066: return "WM_VSCROLLCLIPBOARD";
4090 case 0x0067: return "WM_DRAWCLIPBOARD";
4091 // mouse messages
4092 case 0x0070: return "WM_MOUSEMOVE";
4093 case 0x0071: return "WM_BUTTON1DOWN";
4094 case 0x0072: return "WM_BUTTON1UP";
4095 case 0x0073: return "WM_BUTTON1DBLCLK";
4096 case 0x0074: return "WM_BUTTON2DOWN";
4097 case 0x0075: return "WM_BUTTON2UP";
4098 case 0x0076: return "WM_BUTTON2DBLCLK";
4099 case 0x0077: return "WM_BUTTON3DOWN";
4100 case 0x0078: return "WM_BUTTON3UP";
4101 case 0x0079: return "WM_BUTTON3DBLCLK";
4102 case 0x007D: return "WM_MOUSEMAP";
4103 case 0x007E: return "WM_VRNDISABLED";
4104 case 0x007F: return "WM_VRNENABLED";
4105 case 0x0410: return "WM_CHORD";
4106 case 0x0411: return "WM_BUTTON1MOTIONSTART";
4107 case 0x0412: return "WM_BUTTON1MOTIONEND";
4108 case 0x0413: return "WM_BUTTON1CLICK";
4109 case 0x0414: return "WM_BUTTON2MOTIONSTART";
4110 case 0x0415: return "WM_BUTTON2MOTIONEND";
4111 case 0x0416: return "WM_BUTTON2CLICK";
4112 case 0x0417: return "WM_BUTTON3MOTIONSTART";
4113 case 0x0418: return "WM_BUTTON3MOTIONEND";
4114 case 0x0419: return "WM_BUTTON3CLICK";
4115 case 0x0420: return "WM_BEGINDRAG";
4116 case 0x0421: return "WM_ENDDRAG";
4117 case 0x0422: return "WM_SINGLESELECT";
4118 case 0x0423: return "WM_OPEN";
4119 case 0x0424: return "WM_CONTEXTMENU";
4120 case 0x0425: return "WM_CONTEXTHELP";
4121 case 0x0426: return "WM_TEXTEDIT";
4122 case 0x0427: return "WM_BEGINSELECT";
4123 case 0x0228: return "WM_ENDSELECT";
4124 case 0x0429: return "WM_PICKUP";
4125 case 0x04C0: return "WM_PENFIRST";
4126 case 0x04FF: return "WM_PENLAST";
4127 case 0x0500: return "WM_MMPMFIRST";
4128 case 0x05FF: return "WM_MMPMLAST";
4129 case 0x0600: return "WM_STDDLGFIRST";
4130 case 0x06FF: return "WM_STDDLGLAST";
4131 case 0x0BD0: return "WM_BIDI_FIRST";
4132 case 0x0BFF: return "WM_BIDI_LAST";
4133 // keyboard input
4134 case 0x007A: return "WM_CHAR";
4135 case 0x007B: return "WM_VIOCHAR";
4136 // DDE messages
4137 case 0x00A0: return "WM_DDE_INITIATE";
4138 case 0x00A1: return "WM_DDE_REQUEST";
4139 case 0x00A2: return "WM_DDE_ACK";
4140 case 0x00A3: return "WM_DDE_DATA";
4141 case 0x00A4: return "WM_DDE_ADVISE";
4142 case 0x00A5: return "WM_DDE_UNADVISE";
4143 case 0x00A6: return "WM_DDE_POKE";
4144 case 0x00A7: return "WM_DDE_EXECUTE";
4145 case 0x00A8: return "WM_DDE_TERMINATE";
4146 case 0x00A9: return "WM_DDE_INITIATEACK";
4147 case 0x00AF: return "WM_DDE_LAST";
4148 // Buttons
4149 case 0x0120: return "BM_CLICK";
4150 case 0x0121: return "BM_QUERYCHECKINDEX";
4151 case 0x0122: return "BM_QUERYHILITE";
4152 case 0x0123: return "BM_SETHILITE";
4153 case 0x0124: return "BM_QUERYCHECK";
4154 case 0x0125: return "BM_SETCHECK";
4155 case 0x0126: return "BM_SETDEFAULT";
4156 case 0x0128: return "BM_AUTOSIZE";
4157 // Combo boxes
4158 case 0x029A: return "CBID_LIST";
4159 case 0x029B: return "CBID_EDIT";
4160 case 0x0170: return "CBM_SHOWLIST";
4161 case 0x0171: return "CBM_HILITE";
4162 case 0x0172: return "CBM_ISLISTSHOWING";
4163 // Edit fields
4164 case 0x0140: return "EM_QUERYCHANGED";
4165 case 0x0141: return "EM_QUERYSEL";
4166 case 0x0142: return "EM_SETSEL";
4167 case 0x0143: return "EM_SETTEXTLIMIT";
4168 case 0x0144: return "EM_CUT";
4169 case 0x0145: return "EM_COPY";
4170 case 0x0146: return "EM_CLEAR";
4171 case 0x0147: return "EM_PASTE";
4172 case 0x0148: return "EM_QUERYFIRSTCHAR";
4173 case 0x0149: return "EM_SETFIRSTCHAR";
4174 case 0x014A: return "EM_QUERYREADONLY";
4175 case 0x014B: return "EM_SETREADONLY";
4176 case 0x014C: return "EM_SETINSERTMODE";
4177 // Listboxes
4178 case 0x0160: return "LM_QUERYITEMCOUNT";
4179 case 0x0161: return "LM_INSERTITEM";
4180 case 0x0162: return "LM_SETOPENINDEX";
4181 case 0x0163: return "LM_DELETEITEM";
4182 case 0x0164: return "LM_SELECTITEM";
4183 case 0x0165: return "LM_QUERYSELECTION";
4184 case 0x0166: return "LM_SETITEMTEXT";
4185 case 0x0167: return "LM_QUERYITEMTEXTLENGTH";
4186 case 0x0168: return "LM_QUERYITEMTEXT";
4187 case 0x0169: return "LM_SETITEMHANDLE";
4188 case 0x016A: return "LM_QUERYITEMHANDLE";
4189 case 0x016B: return "LM_SEARCHSTRING";
4190 case 0x016C: return "LM_SETITEMHEIGHT";
4191 case 0x016D: return "LM_QUERYTOPINDEX";
4192 case 0x016E: return "LM_DELETEALL";
4193 case 0x016F: return "LM_INSERTMULITEMS";
4194 case 0x0660: return "LM_SETITEMWIDTH";
4195 // Menus
4196 case 0x0180: return "MM_INSERTITEM";
4197 case 0x0181: return "MM_DELETEITEM";
4198 case 0x0182: return "MM_QUERYITEM";
4199 case 0x0183: return "MM_SETITEM";
4200 case 0x0184: return "MM_QUERYITEMCOUNT";
4201 case 0x0185: return "MM_STARTMENUMODE";
4202 case 0x0186: return "MM_ENDMENUMODE";
4203 case 0x0188: return "MM_REMOVEITEM";
4204 case 0x0189: return "MM_SELECTITEM";
4205 case 0x018A: return "MM_QUERYSELITEMID";
4206 case 0x018B: return "MM_QUERYITEMTEXT";
4207 case 0x018C: return "MM_QUERYITEMTEXTLENGTH";
4208 case 0x018D: return "MM_SETITEMHANDLE";
4209 case 0x018E: return "MM_SETITEMTEXT";
4210 case 0x018F: return "MM_ITEMPOSITIONFROMID";
4211 case 0x0190: return "MM_ITEMIDFROMPOSITION";
4212 case 0x0191: return "MM_QUERYITEMATTR";
4213 case 0x0192: return "MM_SETITEMATTR";
4214 case 0x0193: return "MM_ISITEMVALID";
4215 case 0x0194: return "MM_QUERYITEMRECT";
4216 case 0x0431: return "MM_QUERYDEFAULTITEMID";
4217 case 0x0432: return "MM_SETDEFAULTITEMID";
4218 // Scrollbars
4219 case 0x01A0: return "SBM_SETSCROLLBAR";
4220 case 0x01A1: return "SBM_SETPOS";
4221 case 0x01A2: return "SBM_QUERYPOS";
4222 case 0x01A3: return "SBM_QUERYRANGE";
4223 case 0x01A6: return "SBM_SETTHUMBSIZE";
4224
4225 // Help messages
4226 case 0x0F00: return "WM_HELPBASE";
4227 case 0x0FFF: return "WM_HELPTOP";
4228 // Beginning of user defined messages
4229 case 0x1000: return "WM_USER";
4230
4231 // wxWindows user defined types
cdf1e714
DW
4232
4233 // listview
61243a51 4234 // case 0x1000 + 0: return "LVM_GETBKCOLOR";
cdf1e714
DW
4235 case 0x1000 + 1: return "LVM_SETBKCOLOR";
4236 case 0x1000 + 2: return "LVM_GETIMAGELIST";
4237 case 0x1000 + 3: return "LVM_SETIMAGELIST";
4238 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
4239 case 0x1000 + 5: return "LVM_GETITEMA";
4240 case 0x1000 + 75: return "LVM_GETITEMW";
4241 case 0x1000 + 6: return "LVM_SETITEMA";
4242 case 0x1000 + 76: return "LVM_SETITEMW";
4243 case 0x1000 + 7: return "LVM_INSERTITEMA";
4244 case 0x1000 + 77: return "LVM_INSERTITEMW";
4245 case 0x1000 + 8: return "LVM_DELETEITEM";
4246 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
4247 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
4248 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
4249 case 0x1000 + 12: return "LVM_GETNEXTITEM";
4250 case 0x1000 + 13: return "LVM_FINDITEMA";
4251 case 0x1000 + 83: return "LVM_FINDITEMW";
4252 case 0x1000 + 14: return "LVM_GETITEMRECT";
4253 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
4254 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
4255 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
4256 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
4257 case 0x1000 + 18: return "LVM_HITTEST";
4258 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
4259 case 0x1000 + 20: return "LVM_SCROLL";
4260 case 0x1000 + 21: return "LVM_REDRAWITEMS";
4261 case 0x1000 + 22: return "LVM_ARRANGE";
4262 case 0x1000 + 23: return "LVM_EDITLABELA";
4263 case 0x1000 + 118: return "LVM_EDITLABELW";
4264 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
4265 case 0x1000 + 25: return "LVM_GETCOLUMNA";
4266 case 0x1000 + 95: return "LVM_GETCOLUMNW";
4267 case 0x1000 + 26: return "LVM_SETCOLUMNA";
4268 case 0x1000 + 96: return "LVM_SETCOLUMNW";
4269 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
4270 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
4271 case 0x1000 + 28: return "LVM_DELETECOLUMN";
4272 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
4273 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
4274 case 0x1000 + 31: return "LVM_GETHEADER";
4275 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
4276 case 0x1000 + 34: return "LVM_GETVIEWRECT";
4277 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
4278 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
4279 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
4280 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
4281 case 0x1000 + 39: return "LVM_GETTOPINDEX";
4282 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
4283 case 0x1000 + 41: return "LVM_GETORIGIN";
4284 case 0x1000 + 42: return "LVM_UPDATE";
4285 case 0x1000 + 43: return "LVM_SETITEMSTATE";
4286 case 0x1000 + 44: return "LVM_GETITEMSTATE";
4287 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
4288 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
4289 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
4290 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
4291 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
4292 case 0x1000 + 48: return "LVM_SORTITEMS";
4293 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
4294 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
4295 case 0x1000 + 51: return "LVM_GETITEMSPACING";
4296 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
4297 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
4298 case 0x1000 + 53: return "LVM_SETICONSPACING";
4299 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
4300 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
4301 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
4302 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
4303 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
4304 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
4305 case 0x1000 + 60: return "LVM_SETHOTITEM";
4306 case 0x1000 + 61: return "LVM_GETHOTITEM";
4307 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
4308 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
4309 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
4310 case 0x1000 + 65: return "LVM_SETWORKAREA";
4311
4312 // tree view
4313 case 0x1100 + 0: return "TVM_INSERTITEMA";
4314 case 0x1100 + 50: return "TVM_INSERTITEMW";
4315 case 0x1100 + 1: return "TVM_DELETEITEM";
4316 case 0x1100 + 2: return "TVM_EXPAND";
4317 case 0x1100 + 4: return "TVM_GETITEMRECT";
4318 case 0x1100 + 5: return "TVM_GETCOUNT";
4319 case 0x1100 + 6: return "TVM_GETINDENT";
4320 case 0x1100 + 7: return "TVM_SETINDENT";
4321 case 0x1100 + 8: return "TVM_GETIMAGELIST";
4322 case 0x1100 + 9: return "TVM_SETIMAGELIST";
4323 case 0x1100 + 10: return "TVM_GETNEXTITEM";
4324 case 0x1100 + 11: return "TVM_SELECTITEM";
4325 case 0x1100 + 12: return "TVM_GETITEMA";
4326 case 0x1100 + 62: return "TVM_GETITEMW";
4327 case 0x1100 + 13: return "TVM_SETITEMA";
4328 case 0x1100 + 63: return "TVM_SETITEMW";
4329 case 0x1100 + 14: return "TVM_EDITLABELA";
4330 case 0x1100 + 65: return "TVM_EDITLABELW";
4331 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
4332 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
4333 case 0x1100 + 17: return "TVM_HITTEST";
4334 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
4335 case 0x1100 + 19: return "TVM_SORTCHILDREN";
4336 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
4337 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
4338 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
4339 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
4340 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
4341 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
4342 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
4343
4344 // header
4345 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
4346 case 0x1200 + 1: return "HDM_INSERTITEMA";
4347 case 0x1200 + 10: return "HDM_INSERTITEMW";
4348 case 0x1200 + 2: return "HDM_DELETEITEM";
4349 case 0x1200 + 3: return "HDM_GETITEMA";
4350 case 0x1200 + 11: return "HDM_GETITEMW";
4351 case 0x1200 + 4: return "HDM_SETITEMA";
4352 case 0x1200 + 12: return "HDM_SETITEMW";
4353 case 0x1200 + 5: return "HDM_LAYOUT";
4354 case 0x1200 + 6: return "HDM_HITTEST";
4355 case 0x1200 + 7: return "HDM_GETITEMRECT";
4356 case 0x1200 + 8: return "HDM_SETIMAGELIST";
4357 case 0x1200 + 9: return "HDM_GETIMAGELIST";
4358 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
4359 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
4360 case 0x1200 + 17: return "HDM_GETORDERARRAY";
4361 case 0x1200 + 18: return "HDM_SETORDERARRAY";
4362 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
4363
4364 // tab control
4365 case 0x1300 + 2: return "TCM_GETIMAGELIST";
4366 case 0x1300 + 3: return "TCM_SETIMAGELIST";
4367 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
4368 case 0x1300 + 5: return "TCM_GETITEMA";
4369 case 0x1300 + 60: return "TCM_GETITEMW";
4370 case 0x1300 + 6: return "TCM_SETITEMA";
4371 case 0x1300 + 61: return "TCM_SETITEMW";
4372 case 0x1300 + 7: return "TCM_INSERTITEMA";
4373 case 0x1300 + 62: return "TCM_INSERTITEMW";
4374 case 0x1300 + 8: return "TCM_DELETEITEM";
4375 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
4376 case 0x1300 + 10: return "TCM_GETITEMRECT";
4377 case 0x1300 + 11: return "TCM_GETCURSEL";
4378 case 0x1300 + 12: return "TCM_SETCURSEL";
4379 case 0x1300 + 13: return "TCM_HITTEST";
4380 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
4381 case 0x1300 + 40: return "TCM_ADJUSTRECT";
4382 case 0x1300 + 41: return "TCM_SETITEMSIZE";
4383 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
4384 case 0x1300 + 43: return "TCM_SETPADDING";
4385 case 0x1300 + 44: return "TCM_GETROWCOUNT";
4386 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
4387 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
4388 case 0x1300 + 47: return "TCM_GETCURFOCUS";
4389 case 0x1300 + 48: return "TCM_SETCURFOCUS";
4390 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
4391 case 0x1300 + 50: return "TCM_DESELECTALL";
4392
4393 // toolbar
61243a51
DW
4394 case WM_USER+1000+1: return "TB_ENABLEBUTTON";
4395 case WM_USER+1000+2: return "TB_CHECKBUTTON";
4396 case WM_USER+1000+3: return "TB_PRESSBUTTON";
4397 case WM_USER+1000+4: return "TB_HIDEBUTTON";
4398 case WM_USER+1000+5: return "TB_INDETERMINATE";
4399 case WM_USER+1000+9: return "TB_ISBUTTONENABLED";
4400 case WM_USER+1000+10: return "TB_ISBUTTONCHECKED";
4401 case WM_USER+1000+11: return "TB_ISBUTTONPRESSED";
4402 case WM_USER+1000+12: return "TB_ISBUTTONHIDDEN";
4403 case WM_USER+1000+13: return "TB_ISBUTTONINDETERMINATE";
4404 case WM_USER+1000+17: return "TB_SETSTATE";
4405 case WM_USER+1000+18: return "TB_GETSTATE";
4406 case WM_USER+1000+19: return "TB_ADDBITMAP";
4407 case WM_USER+1000+20: return "TB_ADDBUTTONS";
4408 case WM_USER+1000+21: return "TB_INSERTBUTTON";
4409 case WM_USER+1000+22: return "TB_DELETEBUTTON";
4410 case WM_USER+1000+23: return "TB_GETBUTTON";
4411 case WM_USER+1000+24: return "TB_BUTTONCOUNT";
4412 case WM_USER+1000+25: return "TB_COMMANDTOINDEX";
4413 case WM_USER+1000+26: return "TB_SAVERESTOREA";
4414 case WM_USER+1000+76: return "TB_SAVERESTOREW";
4415 case WM_USER+1000+27: return "TB_CUSTOMIZE";
4416 case WM_USER+1000+28: return "TB_ADDSTRINGA";
4417 case WM_USER+1000+77: return "TB_ADDSTRINGW";
4418 case WM_USER+1000+29: return "TB_GETITEMRECT";
4419 case WM_USER+1000+30: return "TB_BUTTONSTRUCTSIZE";
4420 case WM_USER+1000+31: return "TB_SETBUTTONSIZE";
4421 case WM_USER+1000+32: return "TB_SETBITMAPSIZE";
4422 case WM_USER+1000+33: return "TB_AUTOSIZE";
4423 case WM_USER+1000+35: return "TB_GETTOOLTIPS";
4424 case WM_USER+1000+36: return "TB_SETTOOLTIPS";
4425 case WM_USER+1000+37: return "TB_SETPARENT";
4426 case WM_USER+1000+39: return "TB_SETROWS";
4427 case WM_USER+1000+40: return "TB_GETROWS";
4428 case WM_USER+1000+42: return "TB_SETCMDID";
4429 case WM_USER+1000+43: return "TB_CHANGEBITMAP";
4430 case WM_USER+1000+44: return "TB_GETBITMAP";
4431 case WM_USER+1000+45: return "TB_GETBUTTONTEXTA";
4432 case WM_USER+1000+75: return "TB_GETBUTTONTEXTW";
4433 case WM_USER+1000+46: return "TB_REPLACEBITMAP";
4434 case WM_USER+1000+47: return "TB_SETINDENT";
4435 case WM_USER+1000+48: return "TB_SETIMAGELIST";
4436 case WM_USER+1000+49: return "TB_GETIMAGELIST";
4437 case WM_USER+1000+50: return "TB_LOADIMAGES";
4438 case WM_USER+1000+51: return "TB_GETRECT";
4439 case WM_USER+1000+52: return "TB_SETHOTIMAGELIST";
4440 case WM_USER+1000+53: return "TB_GETHOTIMAGELIST";
4441 case WM_USER+1000+54: return "TB_SETDISABLEDIMAGELIST";
4442 case WM_USER+1000+55: return "TB_GETDISABLEDIMAGELIST";
4443 case WM_USER+1000+56: return "TB_SETSTYLE";
4444 case WM_USER+1000+57: return "TB_GETSTYLE";
4445 case WM_USER+1000+58: return "TB_GETBUTTONSIZE";
4446 case WM_USER+1000+59: return "TB_SETBUTTONWIDTH";
4447 case WM_USER+1000+60: return "TB_SETMAXTEXTROWS";
4448 case WM_USER+1000+61: return "TB_GETTEXTROWS";
4449 case WM_USER+1000+41: return "TB_GETBITMAPFLAGS";
cdf1e714
DW
4450
4451 default:
4452 static char s_szBuf[128];
61243a51 4453 sprintf(s_szBuf, "<unknown message = %d>", nMessage);
cdf1e714 4454 return s_szBuf;
86de7616 4455 }
cdf1e714 4456 return NULL;
61243a51 4457} // end of wxGetMessageName
86de7616 4458
11e59d47
DW
4459#endif // __WXDEBUG__
4460
61243a51
DW
4461static void TranslateKbdEventToMouse(
4462 wxWindow* pWin
4463, int* pX
4464, int* pY
4465, ULONG* pFlags
4466)
4467{
4468 //
4469 // Construct the key mask
4470 ULONG& fwKeys = *pFlags;
4471
4472 fwKeys = VK_BUTTON2;
4473 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
4474 fwKeys |= VK_CTRL;
4475 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
4476 fwKeys |= VK_SHIFT;
4477
4478 //
4479 // Simulate right mouse button click
4480 //
4481 POINTL vPoint;
4482
4483 ::WinQueryMsgPos(vHabmain, &vPoint);
4484 *pX = vPoint.x;
4485 *pY = vPoint.y;
4486
4487 pWin->ScreenToClient(pX, pY);
4488} // end of TranslateKbdEventToMouse
4489
cd212ee4
DW
4490// Find the wxWindow at the current mouse position, returning the mouse
4491// position.
f44fdfb0
DW
4492wxWindow* wxFindWindowAtPointer(
4493 wxPoint& rPt
4494)
cd212ee4
DW
4495{
4496 return wxFindWindowAtPoint(wxGetMousePosition());
4497}
4498
f44fdfb0
DW
4499wxWindow* wxFindWindowAtPoint(
4500 const wxPoint& rPt
4501)
cd212ee4 4502{
f44fdfb0 4503 POINTL vPt2;
cd212ee4 4504
f44fdfb0
DW
4505 vPt2.x = rPt.x;
4506 vPt2.y = rPt.y;
cd212ee4 4507
f44fdfb0
DW
4508 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
4509 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
4510 HWND hWnd = hWndHit;
4511
4512 //
cd212ee4 4513 // Try to find a window with a wxWindow associated with it
f44fdfb0
DW
4514 //
4515 while (!pWin && (hWnd != 0))
cd212ee4 4516 {
f44fdfb0
DW
4517 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
4518 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
cd212ee4 4519 }
f44fdfb0 4520 return pWin;
cd212ee4
DW
4521}
4522
f44fdfb0
DW
4523// Get the current mouse position.
4524wxPoint wxGetMousePosition()
4525{
4526 POINTL vPt;
4527
4528 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
4529 return wxPoint(vPt.x, vPt.y);
4530}
cd212ee4 4531