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