Fixed bug introduced by previous change (patch #1395852)
[wxWidgets.git] / src / os2 / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/window.cpp
3 // Purpose: wxWindow
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/12/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //
13 // For compilers that support precompilation, includes "wx.h".
14 //
15 #include "wx/wxprec.h"
16
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/checkbox.h"
32 #include "wx/combobox.h"
33 #include "wx/dialog.h"
34 #include "wx/frame.h"
35 #include "wx/listbox.h"
36 #include "wx/button.h"
37 #include "wx/bmpbuttn.h"
38 #include "wx/msgdlg.h"
39 #include "wx/scrolwin.h"
40 #include "wx/radiobox.h"
41 #include "wx/radiobut.h"
42 #include "wx/slider.h"
43 #include "wx/statbox.h"
44 #include "wx/statusbr.h"
45 #include "wx/toolbar.h"
46 #include "wx/settings.h"
47 #include <stdio.h>
48 #endif
49
50 #if wxUSE_OWNER_DRAWN
51 #include "wx/ownerdrw.h"
52 #endif
53
54 #if wxUSE_DRAG_AND_DROP
55 #include "wx/dnd.h"
56 #endif
57
58 #include "wx/menuitem.h"
59 #include "wx/log.h"
60
61 #include "wx/os2/private.h"
62
63 #if wxUSE_TOOLTIPS
64 #include "wx/tooltip.h"
65 #endif
66
67 #if wxUSE_NOTEBOOK
68 #include "wx/notebook.h"
69 #endif
70
71 #if wxUSE_CARET
72 #include "wx/caret.h"
73 #endif // wxUSE_CARET
74
75 #include "wx/intl.h"
76 #include "wx/log.h"
77
78
79 #include "wx/textctrl.h"
80
81 #include <string.h>
82
83 //
84 // Place compiler, OS specific includes here
85 //
86
87 //
88 // Standard macros -- these are for OS/2 PM, but most GUI's have something similar
89 //
90 #ifndef GET_X_LPARAM
91 //
92 // SHORT1FROMMP -- LOWORD
93 //
94 #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp))
95 //
96 // SHORT2FROMMP -- HIWORD
97 //
98 #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16))
99 #endif // GET_X_LPARAM
100
101 #ifndef CW_USEDEFAULT
102 # define CW_USEDEFAULT ((int)0x80000000)
103 #endif
104
105 #ifndef VK_OEM_1
106 #define VK_OEM_1 0xBA
107 #define VK_OEM_PLUS 0xBB
108 #define VK_OEM_COMMA 0xBC
109 #define VK_OEM_MINUS 0xBD
110 #define VK_OEM_PERIOD 0xBE
111 #define VK_OEM_2 0xBF
112 #define VK_OEM_3 0xC0
113 #define VK_OEM_4 0xDB
114 #define VK_OEM_5 0xDC
115 #define VK_OEM_6 0xDD
116 #define VK_OEM_7 0xDE
117 #endif
118
119 // ---------------------------------------------------------------------------
120 // global variables
121 // ---------------------------------------------------------------------------
122
123 //
124 // The last PM message we got (MT-UNSAFE)
125 //
126 QMSG s_currentMsg;
127
128 #if wxUSE_MENUS_NATIVE
129 wxMenu* wxCurrentPopupMenu = NULL;
130 #endif // wxUSE_MENUS_NATIVE
131
132 // ---------------------------------------------------------------------------
133 // private functions
134 // ---------------------------------------------------------------------------
135
136 //
137 // the window proc for all our windows; most gui's have something similar
138 //
139 MRESULT EXPENTRY wxWndProc( HWND hWnd
140 ,ULONG message
141 ,MPARAM mp1
142 ,MPARAM mp2
143 );
144
145 #ifdef __WXDEBUG__
146 const wxChar *wxGetMessageName(int message);
147 #endif //__WXDEBUG__
148
149 wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin
150 ,short* pnX
151 ,short* pnY
152 );
153 void wxRemoveHandleAssociation(wxWindowOS2* pWin);
154 void wxAssociateWinWithHandle( HWND hWnd
155 ,wxWindowOS2* pWin
156 );
157 wxWindow* wxFindWinFromHandle(WXHWND hWnd);
158
159 //
160 // get the current state of SHIFT/CTRL keys
161 //
162 static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
163 static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
164
165 static wxWindow* gpWinBeingCreated = NULL;
166
167 // ---------------------------------------------------------------------------
168 // event tables
169 // ---------------------------------------------------------------------------
170
171 // in wxUniv-OS/2 this class is abstract because it doesn't have DoPopupMenu()
172 // method
173 #ifdef __WXUNIVERSAL__
174 IMPLEMENT_ABSTRACT_CLASS(wxWindowOS2, wxWindowBase)
175 #else // __WXPM__
176 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
177 #endif // __WXUNIVERSAL__/__WXPM__
178
179 BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
180 EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
181 EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
182 EVT_IDLE(wxWindowOS2::OnIdle)
183 EVT_SET_FOCUS(wxWindowOS2::OnSetFocus)
184 END_EVENT_TABLE()
185
186 // ===========================================================================
187 // implementation
188 // ===========================================================================
189
190 // ---------------------------------------------------------------------------
191 // wxWindow utility functions
192 // ---------------------------------------------------------------------------
193
194 //
195 // Find an item given the PM Window id
196 //
197 wxWindow* wxWindowOS2::FindItem(
198 long lId
199 ) const
200 {
201 #if wxUSE_CONTROLS
202 wxControl* pItem = wxDynamicCast(this, wxControl);
203
204 if (pItem)
205 {
206 //
207 // I it we or one of our "internal" children?
208 //
209 if (pItem->GetId() == lId
210 #ifndef __WXUNIVERSAL__
211 || (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)
212 #endif
213 )
214 {
215 return pItem;
216 }
217 }
218 #endif // wxUSE_CONTROLS
219
220 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
221
222 while (current)
223 {
224 wxWindow* pChildWin = current->GetData();
225 wxWindow* pWnd = pChildWin->FindItem(lId);
226
227 if (pWnd)
228 return pWnd;
229
230 current = current->GetNext();
231 }
232 return(NULL);
233 } // end of wxWindowOS2::FindItem
234
235 //
236 // Find an item given the PM Window handle
237 //
238 wxWindow* wxWindowOS2::FindItemByHWND(
239 WXHWND hWnd
240 , bool bControlOnly
241 ) const
242 {
243 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
244
245 while (current)
246 {
247 wxWindow* pParent = current->GetData();
248
249 //
250 // Do a recursive search.
251 //
252 wxWindow* pWnd = pParent->FindItemByHWND(hWnd);
253
254 if (pWnd)
255 return(pWnd);
256
257 if (!bControlOnly
258 #if wxUSE_CONTROLS
259 || pParent->IsKindOf(CLASSINFO(wxControl))
260 #endif // wxUSE_CONTROLS
261 )
262 {
263 wxWindow* pItem = current->GetData();
264
265 if (pItem->GetHWND() == hWnd)
266 return(pItem);
267 else
268 {
269 if (pItem->ContainsHWND(hWnd))
270 return(pItem);
271 }
272 }
273 current = current->GetNext();
274 }
275 return(NULL);
276 } // end of wxWindowOS2::FindItemByHWND
277
278 //
279 // Default command handler
280 //
281 bool wxWindowOS2::OS2Command( WXUINT WXUNUSED(uParam),
282 WXWORD WXUNUSED(uId) )
283 {
284 return false;
285 }
286
287 // ----------------------------------------------------------------------------
288 // constructors and such
289 // ----------------------------------------------------------------------------
290
291 void wxWindowOS2::Init()
292 {
293 //
294 // PM specific
295 //
296 m_bWinCaptured = false;
297
298 m_fnOldWndProc = NULL;
299 m_bUseCtl3D = false;
300 m_bMouseInWindow = false;
301 m_bLastKeydownProcessed = false;
302 m_pChildrenDisabled = NULL;
303
304 //
305 // wxWnd
306 //
307 m_hMenu = 0L;
308 m_hWnd = 0L;
309 m_hWndScrollBarHorz = 0L;
310 m_hWndScrollBarVert = 0L;
311
312 memset(&m_vWinSwp, '\0', sizeof (SWP));
313
314 //
315 // Pass WM_GETDLGCODE to DefWindowProc()
316 //
317 m_lDlgCode = 0;
318
319 m_nXThumbSize = 0;
320 m_nYThumbSize = 0;
321 m_bBackgroundTransparent = false;
322
323 //
324 // As all windows are created with WS_VISIBLE style...
325 //
326 m_isShown = true;
327
328 #if wxUSE_MOUSEEVENT_HACK
329 m_lLastMouseX =
330 m_lLastMouseY = -1;
331 m_nLastMouseEvent = -1;
332 #endif // wxUSE_MOUSEEVENT_HACK
333 } // wxWindowOS2::Init
334
335 //
336 // Destructor
337 //
338 wxWindowOS2::~wxWindowOS2()
339 {
340 m_isBeingDeleted = true;
341
342 for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
343 {
344 wxTopLevelWindow* pFrame = wxDynamicCast(pWin, wxTopLevelWindow);
345
346 if (pFrame)
347 {
348 if (pFrame->GetLastFocus() == this)
349 pFrame->SetLastFocus(NULL);
350 }
351 }
352
353 DestroyChildren();
354
355 if (m_hWnd)
356 {
357 if(!::WinDestroyWindow(GetHWND()))
358 wxLogLastError(wxT("DestroyWindow"));
359 //
360 // remove hWnd <-> wxWindow association
361 //
362 wxRemoveHandleAssociation(this);
363 }
364 delete m_pChildrenDisabled;
365 } // end of wxWindowOS2::~wxWindowOS2
366
367 // real construction (Init() must have been called before!)
368 bool wxWindowOS2::Create( wxWindow* pParent,
369 wxWindowID vId,
370 const wxPoint& rPos,
371 const wxSize& rSize,
372 long lStyle,
373 const wxString& rName )
374 {
375 HWND hParent = NULLHANDLE;
376 ULONG ulCreateFlags = 0;
377 WXDWORD dwExStyle = 0;
378
379 wxCHECK_MSG(pParent, false, wxT("can't create wxWindow without parent"));
380
381 #if wxUSE_STATBOX
382 //
383 // wxGTK doesn't allow to create controls with static box as the parent so
384 // this will result in a crash when the program is ported to wxGTK - warn
385 // about it
386 //
387 // the correct solution is to create the controls as siblings of the
388 // static box
389 //
390 wxASSERT_MSG( !wxDynamicCast(pParent, wxStaticBox),
391 _T("wxStaticBox can't be used as a window parent!") );
392 #endif // wxUSE_STATBOX
393
394 // Ensure groupbox backgrounds are painted
395 if (IsKindOf(CLASSINFO(wxPanel)))
396 lStyle &= ~wxCLIP_CHILDREN;
397
398 if ( !CreateBase( pParent
399 ,vId
400 ,rPos
401 ,rSize
402 ,lStyle
403 ,wxDefaultValidator
404 ,rName
405 ))
406 return false;
407
408 if (pParent)
409 {
410 pParent->AddChild(this);
411 hParent = GetWinHwnd(pParent);
412
413 if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)))
414 ulCreateFlags |= WS_CLIPSIBLINGS;
415 }
416
417 //
418 // Most wxSTYLES are really PM Class specific styles and will be
419 // set in those class create procs. PM's basic windows styles are
420 // very limited.
421 //
422 ulCreateFlags |= OS2GetCreateWindowFlags(&dwExStyle);
423
424
425 #ifdef __WXUNIVERSAL__
426 // no 3d effects, we draw them ourselves
427 WXDWORD exStyle = 0;
428 #endif // !wxUniversal
429 if (lStyle & wxPOPUP_WINDOW)
430 {
431 ulCreateFlags &= ~WS_VISIBLE;
432 m_isShown = false;
433 }
434 else
435 {
436 ulCreateFlags |= WS_VISIBLE;
437 }
438
439 //
440 // Generic OS/2 Windows have no Control Data but other classes
441 // that call OS2Create may have some.
442 //
443 return(OS2Create( (PSZ)wxCanvasClassName
444 ,rName.c_str()
445 ,ulCreateFlags
446 ,rPos
447 ,rSize
448 ,NULL // Control Data
449 ,dwExStyle
450 ,true // Child
451 ));
452 } // end of wxWindowOS2::Create
453
454 // ---------------------------------------------------------------------------
455 // basic operations
456 // ---------------------------------------------------------------------------
457
458 void wxWindowOS2::SetFocus()
459 {
460 HWND hWnd = GetHwnd();
461 wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
462
463 if (hWnd)
464 ::WinSetFocus(HWND_DESKTOP, hWnd);
465 } // end of wxWindowOS2::SetFocus
466
467 void wxWindowOS2::SetFocusFromKbd()
468 {
469 //
470 // Nothing else to do under OS/2
471 //
472 wxWindowBase::SetFocusFromKbd();
473 } // end of wxWindowOS2::SetFocus
474
475 wxWindow* wxWindowBase::DoFindFocus()
476 {
477 HWND hWnd = ::WinQueryFocus(HWND_DESKTOP);
478
479 if (hWnd)
480 {
481 return wxFindWinFromHandle((WXHWND)hWnd);
482 }
483 return NULL;
484 } // wxWindowBase::DoFindFocus
485
486 bool wxWindowOS2::Enable( bool bEnable )
487 {
488 if (!wxWindowBase::Enable(bEnable))
489 return false;
490
491 HWND hWnd = GetHwnd();
492
493 if ( hWnd )
494 ::WinEnableWindow(hWnd, (BOOL)bEnable);
495
496 //
497 // The logic below doesn't apply to the top level windows -- otherwise
498 // showing a modal dialog would result in total greying out (and ungreying
499 // out later) of everything which would be really ugly
500 //
501 if (IsTopLevel())
502 return true;
503
504 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
505
506 while (node)
507 {
508 wxWindow* pChild = node->GetData();
509
510 if (bEnable)
511 {
512 //
513 // Enable the child back unless it had been disabled before us
514 //
515 if (!m_pChildrenDisabled || !m_pChildrenDisabled->Find(pChild))
516 pChild->Enable();
517 }
518 else // we're being disabled
519 {
520 if (pChild->IsEnabled())
521 {
522 //
523 // Disable it as children shouldn't stay enabled while the
524 // parent is not
525 //
526 pChild->Disable();
527 }
528 else // child already disabled, remember it
529 {
530 //
531 // Have we created the list of disabled children already?
532 //
533 if (!m_pChildrenDisabled)
534 m_pChildrenDisabled = new wxWindowList;
535 m_pChildrenDisabled->Append(pChild);
536 }
537 }
538 node = node->GetNext();
539 }
540 if (bEnable && m_pChildrenDisabled)
541 {
542 //
543 // We don't need this list any more, don't keep unused memory
544 //
545 delete m_pChildrenDisabled;
546 m_pChildrenDisabled = NULL;
547 }
548 return true;
549 } // end of wxWindowOS2::Enable
550
551 bool wxWindowOS2::Show( bool bShow )
552 {
553 if (!wxWindowBase::Show(bShow))
554 return false;
555
556 HWND hWnd = GetHwnd();
557
558 ::WinShowWindow(hWnd, bShow);
559
560 if (bShow)
561 {
562 ::WinSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
563 }
564 return true;
565 } // end of wxWindowOS2::Show
566
567 void wxWindowOS2::Raise()
568 {
569 ::WinSetWindowPos(GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_ACTIVATE);
570 } // end of wxWindowOS2::Raise
571
572 void wxWindowOS2::Lower()
573 {
574 ::WinSetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE);
575 } // end of wxWindowOS2::Lower
576
577 void wxWindowOS2::SetLabel( const wxString& label )
578 {
579 ::WinSetWindowText(GetHwnd(), (PSZ)label.c_str());
580 } // end of wxWindowOS2::SetLabel
581
582 wxString wxWindowOS2::GetLabel() const
583 {
584 return wxGetWindowText(GetHWND());
585 } // end of wxWindowOS2::GetLabel
586
587 void wxWindowOS2::DoCaptureMouse()
588 {
589 HWND hWnd = GetHwnd();
590
591 if (hWnd && !m_bWinCaptured)
592 {
593 ::WinSetCapture(HWND_DESKTOP, hWnd);
594 m_bWinCaptured = true;
595 }
596 } // end of wxWindowOS2::DoCaptureMouse
597
598 void wxWindowOS2::DoReleaseMouse()
599 {
600 if (m_bWinCaptured)
601 {
602 ::WinSetCapture(HWND_DESKTOP, NULLHANDLE);
603 m_bWinCaptured = false;
604 }
605 } // end of wxWindowOS2::ReleaseMouse
606
607 /* static */ wxWindow* wxWindowBase::GetCapture()
608 {
609 HWND hwnd = ::WinQueryCapture(HWND_DESKTOP);
610 return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
611 } // end of wxWindowBase::GetCapture
612
613 bool wxWindowOS2::SetFont( const wxFont& rFont )
614 {
615 if (!wxWindowBase::SetFont(rFont))
616 {
617 // nothing to do
618 return false;
619 }
620
621 HWND hWnd = GetHwnd();
622
623 wxOS2SetFont( hWnd, rFont );
624 return true;
625 } // end of wxWindowOS2::SetFont
626
627 // check if base implementation is OK
628 bool wxWindowOS2::SetCursor( const wxCursor& rCursor)
629 {
630 if ( !wxWindowBase::SetCursor(rCursor))
631 {
632 // no change
633 return false;
634 }
635
636 if ( m_cursor.Ok() ) {
637 HWND hWnd = GetHwnd();
638 POINTL vPoint;
639 RECTL vRect;
640
641 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
642 ::WinQueryWindowRect(hWnd, &vRect);
643
644 if (::WinPtInRect(vHabmain, &vRect, &vPoint) && !wxIsBusy())
645 {
646 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR());
647 }
648 }
649 return true;
650 } // end of wxWindowOS2::SetCursor
651
652 void wxWindowOS2::WarpPointer(
653 int nXPos
654 , int nYPos
655 )
656 {
657 int nX = nXPos;
658 int nY = nYPos;
659 RECTL vRect;
660
661 ::WinQueryWindowRect(GetHwnd(), &vRect);
662 nX += vRect.xLeft;
663 nY += vRect.yBottom;
664
665 ::WinSetPointerPos(HWND_DESKTOP, (LONG)nX, (LONG)(nY));
666 } // end of wxWindowOS2::WarpPointer
667
668
669 // ---------------------------------------------------------------------------
670 // scrolling stuff
671 // ---------------------------------------------------------------------------
672
673 int wxWindowOS2::GetScrollPos(
674 int nOrient
675 ) const
676 {
677 if (nOrient == wxHORIZONTAL)
678 return((int)::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
679 else
680 return((int)::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
681 } // end of wxWindowOS2::GetScrollPos
682
683 int wxWindowOS2::GetScrollRange(
684 int nOrient
685 ) const
686 {
687 MRESULT mr;
688
689 if (nOrient == wxHORIZONTAL)
690 mr = ::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
691 else
692 mr = ::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
693 return((int)SHORT2FROMMR(mr));
694 } // end of wxWindowOS2::GetScrollRange
695
696 int wxWindowOS2::GetScrollThumb(
697 int nOrient
698 ) const
699 {
700 if (nOrient == wxHORIZONTAL )
701 return m_nXThumbSize;
702 else
703 return m_nYThumbSize;
704 } // end of wxWindowOS2::GetScrollThumb
705
706 void wxWindowOS2::SetScrollPos(
707 int nOrient
708 , int nPos
709 , bool WXUNUSED(bRefresh)
710 )
711 {
712 if (nOrient == wxHORIZONTAL )
713 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
714 else
715 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
716 } // end of wxWindowOS2::SetScrollPos
717
718 void wxWindowOS2::SetScrollbar( int nOrient,
719 int nPos,
720 int nThumbVisible,
721 int nRange,
722 bool WXUNUSED(bRefresh) )
723 {
724 HWND hWnd = GetHwnd();
725 int nOldRange = nRange - nThumbVisible;
726 int nRange1 = nOldRange;
727 int nPageSize = nThumbVisible;
728 int nVSBWidth = wxSystemSettingsNative::GetMetric(wxSYS_VSCROLL_X,
729 this);
730 int nHSBHeight = wxSystemSettingsNative::GetMetric(wxSYS_HSCROLL_Y,
731 this);
732
733 SBCDATA vInfo;
734 ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT;
735 SWP vSwp;
736 SWP vSwpOwner;
737 HWND hWndParent;
738 HWND hWndClient;
739 wxWindow* pParent = GetParent();
740
741 if (pParent && pParent->IsKindOf(CLASSINFO(wxFrame)))
742 {
743 wxFrame* pFrame;
744
745 pFrame = wxDynamicCast(pParent, wxFrame);
746 hWndParent = pFrame->GetFrame();
747 hWndClient = GetHwndOf(pParent);
748 }
749 else
750 {
751 if (pParent)
752 hWndParent = GetHwndOf(pParent);
753 else
754 hWndParent = GetHwnd();
755 hWndClient = hWndParent;
756 }
757 ::WinQueryWindowPos(hWndClient, &vSwp);
758 ::WinQueryWindowPos(hWnd, &vSwpOwner);
759
760 if (nPageSize > 1 && nRange > 0)
761 {
762 nRange1 += (nPageSize - 1);
763 }
764
765 vInfo.cb = sizeof(SBCDATA);
766 vInfo.posFirst = 0;
767 vInfo.posLast = (SHORT)nRange1;
768 vInfo.posThumb = (SHORT)nPos;
769
770 if (nOrient == wxHORIZONTAL )
771 {
772 ulStyle |= SBS_HORZ;
773 if (m_hWndScrollBarHorz == 0L)
774 {
775 //
776 // Since the scrollbars are usually created before the owner is
777 // sized either via an OnSize event directly or via sizers or
778 // layout constraints, we will initially just use the coords of
779 // the parent window (this is usually a frame client window). But
780 // the bars themselves, are children of the parent frame (i.e
781 // siblings of the frame client. The owner, however is the actual
782 // window being scrolled (or at least the one responsible for
783 // handling the scroll events). The owner will be resized later,
784 // as it is usually a child of a top level window, and when that
785 // is done its scrollbars will be resized and repositioned as well.
786 //
787 m_hWndScrollBarHorz = ::WinCreateWindow( hWndParent
788 ,WC_SCROLLBAR
789 ,(PSZ)NULL
790 ,ulStyle
791 ,vSwp.x
792 ,vSwp.y
793 ,vSwp.cx - nVSBWidth
794 ,nHSBHeight
795 ,hWnd
796 ,HWND_TOP
797 ,60000
798 ,&vInfo
799 ,NULL
800 );
801 }
802 else
803 {
804 //
805 // The owner (the scrolled window) is a child of the Frame's
806 // client window, usually. The scrollbars are children of the
807 // frame, itself, and thus are positioned relative to the frame's
808 // origin, not the frame's client window origin.
809 // The starting x position is the same as the starting x position
810 // of the owner, but in terms of the parent frame.
811 // The starting y position is wxSYS_HSCROLL_Y pels below the
812 // origin of the owner in terms of the parent frame.
813 // The horz bar is the same width as the owner and wxSYS_HSCROLL_Y
814 // pels high.
815 //
816 if (nRange1 >= nThumbVisible)
817 {
818 ::WinSetWindowPos( m_hWndScrollBarHorz
819 ,HWND_TOP
820 ,vSwp.x + vSwpOwner.x
821 ,(vSwp.y + vSwpOwner.y) - nHSBHeight
822 ,vSwpOwner.cx
823 ,nHSBHeight
824 ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER
825 );
826 ::WinSendMsg( m_hWndScrollBarHorz
827 ,SBM_SETSCROLLBAR
828 ,(MPARAM)nPos
829 ,MPFROM2SHORT(0, (SHORT)nRange1)
830 );
831 ::WinSendMsg( m_hWndScrollBarHorz
832 ,SBM_SETTHUMBSIZE
833 ,MPFROM2SHORT( (SHORT)nThumbVisible
834 ,(SHORT)nRange1
835 )
836 ,(MPARAM)0
837 );
838 }
839 else
840 ::WinShowWindow(m_hWndScrollBarHorz, FALSE);
841 }
842 }
843 else
844 {
845 ulStyle |= SBS_VERT;
846 if (m_hWndScrollBarVert == 0L)
847 {
848 //
849 // Since the scrollbars are usually created before the owner is
850 // sized either via an OnSize event directly or via sizers or
851 // layout constraints, we will initially just use the coords of
852 // the parent window (this is usually a frame client window). But
853 // the bars themselves, are children of the parent frame (i.e
854 // siblings of the frame client. The owner, however is the actual
855 // window being scrolled (or at least the one responsible for
856 // handling the scroll events). The owner will be resized later,
857 // as it is usually a child of a top level window, and when that
858 // is done its scrollbars will be resized and repositioned as well.
859 //
860 m_hWndScrollBarVert = ::WinCreateWindow( hWndParent
861 ,WC_SCROLLBAR
862 ,(PSZ)NULL
863 ,ulStyle
864 ,vSwp.x + vSwp.cx - nVSBWidth
865 ,vSwp.y + nHSBHeight
866 ,nVSBWidth
867 ,vSwp.cy - nHSBHeight
868 ,hWnd
869 ,HWND_TOP
870 ,60001
871 ,&vInfo
872 ,NULL
873 );
874 }
875 else
876 {
877 //
878 // The owner (the scrolled window) is a child of the Frame's
879 // client window, usually. The scrollbars are children of the
880 // frame, itself and thus are positioned relative to the frame's
881 // origin, not the frame's client window's origin.
882 // Thus, the x position will be frame client's x (usually a few
883 // pels inside the parent frame, plus the width of the owner.
884 // Since we may be using sizers or layout constraints for multiple
885 // child scrolled windows, the y position will be the frame client's
886 // y pos plus the scrolled windows y position, yielding the y
887 // position of the scrollbar relative to the parent frame (the vert
888 // scrollbar is on the right and starts at the bottom of the
889 // owner window).
890 // It is wxSYS_VSCROLL_X pels wide and the same height as the owner.
891 //
892 if (nRange1 >= nThumbVisible)
893 {
894 ::WinSetWindowPos( m_hWndScrollBarVert
895 ,HWND_TOP
896 ,vSwp.x + vSwpOwner.x + vSwpOwner.cx
897 ,vSwp.y + vSwpOwner.y
898 ,nVSBWidth
899 ,vSwpOwner.cy
900 ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
901 );
902 ::WinSendMsg( m_hWndScrollBarVert
903 ,SBM_SETSCROLLBAR
904 ,(MPARAM)nPos
905 ,MPFROM2SHORT(0, (SHORT)nRange1)
906 );
907 ::WinSendMsg( m_hWndScrollBarVert
908 ,SBM_SETTHUMBSIZE
909 ,MPFROM2SHORT( (SHORT)nThumbVisible
910 ,(SHORT)nRange1
911 )
912 ,(MPARAM)0
913 );
914 }
915 else
916 ::WinShowWindow(m_hWndScrollBarVert, FALSE);
917 }
918 m_nYThumbSize = nThumbVisible;
919 }
920 } // end of wxWindowOS2::SetScrollbar
921
922
923 void wxWindowOS2::ScrollWindow( int nDx,
924 int nDy,
925 const wxRect* pRect )
926 {
927 RECTL vRect;
928
929 ::WinQueryWindowRect(GetHwnd(), &vRect);
930 int height = vRect.yTop;
931 if (pRect)
932 {
933 vRect.xLeft = pRect->x;
934 vRect.yTop = height - pRect->y;
935 vRect.xRight = pRect->x + pRect->width;
936 vRect.yBottom = vRect.yTop - pRect->height;
937 }
938 nDy *= -1; // flip the sign of Dy as OS/2 is opposite Windows.
939 ::WinScrollWindow( GetHwnd()
940 ,(LONG)nDx
941 ,(LONG)nDy
942 ,&vRect
943 ,&vRect
944 ,NULL
945 ,NULL
946 ,SW_SCROLLCHILDREN | SW_INVALIDATERGN
947 );
948 } // end of wxWindowOS2::ScrollWindow
949
950 // ---------------------------------------------------------------------------
951 // subclassing
952 // ---------------------------------------------------------------------------
953
954 void wxWindowOS2::SubclassWin(
955 WXHWND hWnd
956 )
957 {
958 HWND hwnd = (HWND)hWnd;
959
960 wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") );
961 wxAssociateWinWithHandle( hWnd
962 ,(wxWindow*)this
963 );
964 if (!wxCheckWindowWndProc( hWnd
965 ,(WXFARPROC)wxWndProc
966 ))
967 {
968 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
969 }
970 else
971 {
972 m_fnOldWndProc = (WXFARPROC)NULL;
973 }
974 } // end of wxWindowOS2::SubclassWin
975
976 void wxWindowOS2::UnsubclassWin()
977 {
978 //
979 // Restore old Window proc
980 //
981 HWND hwnd = GetHWND();
982
983 if (m_hWnd)
984 {
985 wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") );
986
987 PFNWP fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP);
988
989 if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc))
990 {
991 WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc);
992 m_fnOldWndProc = 0;
993 }
994 }
995 } // end of wxWindowOS2::UnsubclassWin
996
997 bool wxCheckWindowWndProc(
998 WXHWND hWnd
999 , WXFARPROC fnWndProc
1000 )
1001 {
1002 static char zBuffer[512];
1003 CLASSINFO vCls;
1004
1005 ::WinQueryClassName((HWND)hWnd, (LONG)512, (PCH)zBuffer);
1006 ::WinQueryClassInfo(wxGetInstance(), (PSZ)zBuffer, &vCls);
1007 return(fnWndProc == (WXFARPROC)vCls.pfnWindowProc);
1008 } // end of WinGuiBase_CheckWindowWndProc
1009
1010 void wxWindowOS2::SetWindowStyleFlag(
1011 long lFlags
1012 )
1013 {
1014 long lFlagsOld = GetWindowStyleFlag();
1015
1016 if (lFlags == lFlagsOld)
1017 return;
1018
1019 //
1020 // Update the internal variable
1021 //
1022 wxWindowBase::SetWindowStyleFlag(lFlags);
1023
1024 //
1025 // Now update the Windows style as well if needed - and if the window had
1026 // been already created
1027 //
1028 if (!GetHwnd())
1029 return;
1030
1031 WXDWORD dwExstyle;
1032 WXDWORD dwExstyleOld;
1033 long lStyle = OS2GetStyle( lFlags
1034 ,&dwExstyle
1035 );
1036 long lStyleOld = OS2GetStyle( lFlagsOld
1037 ,&dwExstyleOld
1038 );
1039
1040 if (lStyle != lStyleOld)
1041 {
1042 //
1043 // Some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by
1044 // this function so instead of simply setting the style to the new
1045 // value we clear the bits which were set in styleOld but are set in
1046 // the new one and set the ones which were not set before
1047 //
1048 long lStyleReal = ::WinQueryWindowULong(GetHwnd(), QWL_STYLE);
1049
1050 lStyleReal &= ~lStyleOld;
1051 lStyleReal |= lStyle;
1052
1053 ::WinSetWindowULong(GetHwnd(), QWL_STYLE, lStyleReal);
1054 }
1055 } // end of wxWindowOS2::SetWindowStyleFlag
1056
1057 WXDWORD wxWindowOS2::OS2GetStyle( long lFlags,
1058 WXDWORD* WXUNUSED(pdwExstyle) ) const
1059 {
1060 WXDWORD dwStyle = 0L;
1061
1062 if (lFlags & wxCLIP_CHILDREN )
1063 dwStyle |= WS_CLIPCHILDREN;
1064
1065 if (lFlags & wxCLIP_SIBLINGS )
1066 dwStyle |= WS_CLIPSIBLINGS;
1067
1068 return dwStyle;
1069 } // end of wxWindowOS2::OS2GetStyle
1070
1071 //
1072 // Make a Windows extended style from the given wxWidgets window style
1073 //
1074 WXDWORD wxWindowOS2::MakeExtendedStyle(
1075 long lStyle
1076 , bool bEliminateBorders
1077 )
1078 {
1079 //
1080 // Simply fill out with wxWindow extended styles. We'll conjure
1081 // something up in OS2Create and all window redrawing pieces later
1082 //
1083 WXDWORD dwStyle = 0;
1084
1085 if (lStyle & wxTRANSPARENT_WINDOW )
1086 dwStyle |= wxTRANSPARENT_WINDOW;
1087
1088 if (!bEliminateBorders)
1089 {
1090 if (lStyle & wxSUNKEN_BORDER)
1091 dwStyle |= wxSUNKEN_BORDER;
1092 if (lStyle & wxDOUBLE_BORDER)
1093 dwStyle |= wxDOUBLE_BORDER;
1094 if (lStyle & wxRAISED_BORDER )
1095 dwStyle |= wxRAISED_BORDER;
1096 if (lStyle & wxSTATIC_BORDER)
1097 dwStyle |= wxSTATIC_BORDER;
1098 }
1099 return dwStyle;
1100 } // end of wxWindowOS2::MakeExtendedStyle
1101
1102 //
1103 // Setup background and foreground colours correctly
1104 //
1105 void wxWindowOS2::SetupColours()
1106 {
1107 if ( GetParent() )
1108 SetBackgroundColour(GetParent()->GetBackgroundColour());
1109 } // end of wxWindowOS2::SetupColours
1110
1111 void wxWindowOS2::OnIdle(
1112 wxIdleEvent& WXUNUSED(rEvent)
1113 )
1114 {
1115 //
1116 // Check if we need to send a LEAVE event
1117 //
1118 if (m_bMouseInWindow)
1119 {
1120 POINTL vPoint;
1121
1122 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
1123 if (::WinWindowFromPoint(HWND_DESKTOP, &vPoint, FALSE) != (HWND)GetHwnd())
1124 {
1125 //
1126 // Generate a LEAVE event
1127 //
1128 m_bMouseInWindow = false;
1129
1130 //
1131 // Unfortunately the mouse button and keyboard state may have changed
1132 // by the time the OnIdle function is called, so 'state' may be
1133 // meaningless.
1134 //
1135 int nState = 0;
1136
1137 if (IsShiftDown())
1138 nState |= KC_SHIFT;
1139 if (IsCtrlDown())
1140 nState |= KC_CTRL;
1141
1142 wxMouseEvent rEvent(wxEVT_LEAVE_WINDOW);
1143
1144 InitMouseEvent( rEvent
1145 ,vPoint.x
1146 ,vPoint.y
1147 ,nState
1148 );
1149 (void)GetEventHandler()->ProcessEvent(rEvent);
1150 }
1151 }
1152 if (wxUpdateUIEvent::CanUpdate(this))
1153 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
1154 } // end of wxWindowOS2::OnIdle
1155
1156 //
1157 // Set this window to be the child of 'parent'.
1158 //
1159 bool wxWindowOS2::Reparent( wxWindow* pParent)
1160 {
1161 if (!wxWindowBase::Reparent(pParent))
1162 return false;
1163
1164 HWND hWndChild = GetHwnd();
1165 HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
1166
1167 ::WinSetParent(hWndChild, hWndParent, TRUE);
1168 return true;
1169 } // end of wxWindowOS2::Reparent
1170
1171 void wxWindowOS2::Update()
1172 {
1173 ::WinUpdateWindow(GetHwnd());
1174 } // end of wxWindowOS2::Update
1175
1176 void wxWindowOS2::Freeze()
1177 {
1178 ::WinSendMsg(GetHwnd(), WM_VRNDISABLED, (MPARAM)0, (MPARAM)0);
1179 } // end of wxWindowOS2::Freeze
1180
1181 void wxWindowOS2::Thaw()
1182 {
1183 ::WinSendMsg(GetHwnd(), WM_VRNENABLED, (MPARAM)TRUE, (MPARAM)0);
1184
1185 //
1186 // We need to refresh everything or otherwise he invalidated area is not
1187 // repainted.
1188 //
1189 Refresh();
1190 } // end of wxWindowOS2::Thaw
1191
1192 void wxWindowOS2::Refresh( bool bEraseBack,
1193 const wxRect* pRect )
1194 {
1195 HWND hWnd = GetHwnd();
1196
1197 if (hWnd)
1198 {
1199 if (pRect)
1200 {
1201 RECTL vOs2Rect;
1202 int height;
1203
1204 ::WinQueryWindowRect(GetHwnd(), &vOs2Rect);
1205 height = vOs2Rect.yTop;
1206 vOs2Rect.xLeft = pRect->x;
1207 vOs2Rect.yTop = height - pRect->y;
1208 vOs2Rect.xRight = pRect->x + pRect->width;
1209 vOs2Rect.yBottom = vOs2Rect.yTop - pRect->height;
1210
1211 ::WinInvalidateRect(hWnd, &vOs2Rect, bEraseBack);
1212 }
1213 else
1214 ::WinInvalidateRect(hWnd, NULL, bEraseBack);
1215 if (m_hWndScrollBarHorz != NULLHANDLE)
1216 ::WinInvalidateRect(m_hWndScrollBarHorz, NULL, TRUE);
1217 if (m_hWndScrollBarVert != NULLHANDLE)
1218 ::WinInvalidateRect(m_hWndScrollBarVert, NULL, TRUE);
1219 }
1220 } // end of wxWindowOS2::Refresh
1221
1222 // ---------------------------------------------------------------------------
1223 // drag and drop
1224 // ---------------------------------------------------------------------------
1225
1226 #if wxUSE_DRAG_AND_DROP
1227 void wxWindowOS2::SetDropTarget(
1228 wxDropTarget* pDropTarget
1229 )
1230 {
1231 m_dropTarget = pDropTarget;
1232 } // end of wxWindowOS2::SetDropTarget
1233 #endif
1234
1235 //
1236 // old style file-manager drag&drop support: we retain the old-style
1237 // DragAcceptFiles in parallel with SetDropTarget.
1238 //
1239 void wxWindowOS2::DragAcceptFiles(
1240 bool bAccept
1241 )
1242 {
1243 HWND hWnd = GetHwnd();
1244
1245 if (hWnd && bAccept)
1246 ::DrgAcceptDroppedFiles(hWnd, NULL, NULL, DO_COPY, 0L);
1247 } // end of wxWindowOS2::DragAcceptFiles
1248
1249 // ----------------------------------------------------------------------------
1250 // tooltips
1251 // ----------------------------------------------------------------------------
1252
1253 #if wxUSE_TOOLTIPS
1254
1255 void wxWindowOS2::DoSetToolTip(
1256 wxToolTip* pTooltip
1257 )
1258 {
1259 wxWindowBase::DoSetToolTip(pTooltip);
1260
1261 if (m_tooltip)
1262 m_tooltip->SetWindow(this);
1263 } // end of wxWindowOS2::DoSetToolTip
1264
1265 #endif // wxUSE_TOOLTIPS
1266
1267 // ---------------------------------------------------------------------------
1268 // moving and resizing
1269 // ---------------------------------------------------------------------------
1270
1271 // Get total size
1272 void wxWindowOS2::DoGetSize(
1273 int* pWidth
1274 , int* pHeight
1275 ) const
1276 {
1277 HWND hWnd;
1278 RECTL vRect;
1279
1280 if (IsKindOf(CLASSINFO(wxFrame)))
1281 {
1282 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1283 hWnd = pFrame->GetFrame();
1284 }
1285 else
1286 hWnd = GetHwnd();
1287
1288 ::WinQueryWindowRect(hWnd, &vRect);
1289
1290 if (pWidth)
1291 *pWidth = vRect.xRight - vRect.xLeft;
1292 if (pHeight )
1293 // OS/2 PM is backwards from windows
1294 *pHeight = vRect.yTop - vRect.yBottom;
1295 } // end of wxWindowOS2::DoGetSize
1296
1297 void wxWindowOS2::DoGetPosition(
1298 int* pX
1299 , int* pY
1300 ) const
1301 {
1302 HWND hWnd = GetHwnd();
1303 SWP vSwp;
1304 POINTL vPoint;
1305 wxWindow* pParent = GetParent();
1306
1307 //
1308 // It would seem that WinQueryWindowRect would be the correlary to
1309 // the WIN32 WinGetRect, but unlike WinGetRect which returns the window
1310 // origin position in screen coordinates, WinQueryWindowRect returns it
1311 // relative to itself, i.e. (0,0). To get the same under PM we must
1312 // us WinQueryWindowPos. This call, unlike the WIN32 call, however,
1313 // returns a position relative to it's parent, so no parent adujstments
1314 // are needed under OS/2. Also, windows should be created using
1315 // wxWindow coordinates, i.e 0,0 is the TOP left so vSwp will already
1316 // reflect that.
1317 //
1318 ::WinQueryWindowPos(hWnd, &vSwp);
1319
1320 vPoint.x = vSwp.x;
1321 vPoint.y = vSwp.y;
1322
1323 //
1324 // We may be faking the client origin. So a window that's really at (0,
1325 // 30) may appear (to wxWin apps) to be at (0, 0).
1326 //
1327 if (pParent)
1328 {
1329 wxPoint vPt(pParent->GetClientAreaOrigin());
1330
1331 vPoint.x -= vPt.x;
1332 vPoint.y -= vPt.y;
1333 }
1334
1335 if (pX)
1336 *pX = vPoint.x;
1337 if (pY)
1338 *pY = vPoint.y;
1339 } // end of wxWindowOS2::DoGetPosition
1340
1341 void wxWindowOS2::DoScreenToClient(
1342 int* pX
1343 , int* pY
1344 ) const
1345 {
1346 HWND hWnd = GetHwnd();
1347 SWP vSwp;
1348
1349 ::WinQueryWindowPos(hWnd, &vSwp);
1350
1351 if (pX)
1352 *pX += vSwp.x;
1353 if (pY)
1354 *pY += vSwp.y;
1355 } // end of wxWindowOS2::DoScreenToClient
1356
1357 void wxWindowOS2::DoClientToScreen(
1358 int* pX
1359 , int* pY
1360 ) const
1361 {
1362 HWND hWnd = GetHwnd();
1363 SWP vSwp;
1364
1365 ::WinQueryWindowPos(hWnd, &vSwp);
1366
1367 if (pX)
1368 *pX += vSwp.x;
1369 if (pY)
1370 *pY += vSwp.y;
1371 } // end of wxWindowOS2::DoClientToScreen
1372
1373 //
1374 // Get size *available for subwindows* i.e. excluding menu bar etc.
1375 // Must be a frame type window
1376 //
1377 void wxWindowOS2::DoGetClientSize(
1378 int* pWidth
1379 , int* pHeight
1380 ) const
1381 {
1382 HWND hWnd = GetHwnd();
1383 RECTL vRect;
1384
1385 ::WinQueryWindowRect(hWnd, &vRect);
1386 if (IsKindOf(CLASSINFO(wxDialog)))
1387 {
1388 RECTL vTitle;
1389 HWND hWndTitle;
1390 //
1391 // For a Dialog we have to explicitly request the client portion.
1392 // For a Frame the hWnd IS the client window
1393 //
1394 hWndTitle = ::WinWindowFromID(hWnd, FID_TITLEBAR);
1395 if (::WinQueryWindowRect(hWndTitle, &vTitle))
1396 {
1397 if (vTitle.yTop - vTitle.yBottom == 0)
1398 {
1399 //
1400 // Dialog has not been created yet, use a default
1401 //
1402 vTitle.yTop = 20;
1403 }
1404 vRect.yTop -= (vTitle.yTop - vTitle.yBottom);
1405 }
1406
1407 ULONG uStyle = ::WinQueryWindowULong(hWnd, QWL_STYLE);
1408
1409 //
1410 // Deal with borders
1411 //
1412 if (uStyle & FCF_DLGBORDER)
1413 {
1414 vRect.xLeft += 4;
1415 vRect.xRight -= 4;
1416 vRect.yTop -= 4;
1417 vRect.yBottom += 4;
1418 }
1419 else if (uStyle & FCF_SIZEBORDER)
1420 {
1421 vRect.xLeft += 4;
1422 vRect.xRight -= 4;
1423 vRect.yTop -= 4;
1424 vRect.yBottom += 4;
1425 }
1426 else if (uStyle & FCF_BORDER)
1427 {
1428 vRect.xLeft += 2;
1429 vRect.xRight -= 2;
1430 vRect.yTop -= 2;
1431 vRect.yBottom += 2;
1432 }
1433 else // make some kind of adjustment or top sizers ram into the titlebar!
1434 {
1435 vRect.xLeft += 3;
1436 vRect.xRight -= 3;
1437 vRect.yTop -= 3;
1438 vRect.yBottom += 3;
1439 }
1440 }
1441 if (pWidth)
1442 *pWidth = vRect.xRight - vRect.xLeft;
1443 if (pHeight)
1444 *pHeight = vRect.yTop - vRect.yBottom;
1445 } // end of wxWindowOS2::DoGetClientSize
1446
1447 void wxWindowOS2::DoMoveWindow(
1448 int nX
1449 , int nY
1450 , int nWidth
1451 , int nHeight
1452 )
1453 {
1454 RECTL vRect;
1455 wxWindow* pParent = GetParent();
1456
1457 /* Due to OS/2's inverted coordinate system, changing the height
1458 of a window requires repositioning all it's children, e.g. if
1459 you want a child of height 100 to be at the top left corner of
1460 the parent you need to position the lower left corner of the
1461 child at (0, (height of parent - 100)), so, obviously, if the
1462 height of the parent changes, the child needs to be repositioned. */
1463 int nHeightDelta;
1464 GetSize(0, &nHeightDelta);
1465 nHeightDelta = nHeight - nHeightDelta;
1466
1467 if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
1468 {
1469 int nOS2Height = GetOS2ParentHeight(pParent);
1470
1471 nY = nOS2Height - (nY + nHeight);
1472 }
1473 else
1474 {
1475 RECTL vRect;
1476
1477 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
1478 nY = vRect.yTop - (nY + nHeight);
1479 }
1480
1481 //
1482 // In the case of a frame whose client is sized, the client cannot be
1483 // large than its parent frame minus its borders! This usually happens
1484 // when using an autosizer to size a frame to precisely hold client
1485 // controls as in the notebook sample.
1486 //
1487 // In this case, we may need to resize both a frame and its client so we
1488 // need a quick calc of the frame border size, then if the frame
1489 // (less its borders) is smaller than the client, size the frame to
1490 // encompass the client with the appropriate border size.
1491 //
1492 if (IsKindOf(CLASSINFO(wxFrame)))
1493 {
1494 RECTL vFRect;
1495 HWND hWndFrame;
1496 int nWidthFrameDelta = 0;
1497 int nHeightFrameDelta = 0;
1498 int nHeightFrame = 0;
1499 int nWidthFrame = 0;
1500 wxFrame* pFrame;
1501
1502 pFrame = wxDynamicCast(this, wxFrame);
1503 hWndFrame = pFrame->GetFrame();
1504 ::WinQueryWindowRect(hWndFrame, &vRect);
1505 ::WinMapWindowPoints(hWndFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
1506 vFRect = vRect;
1507 ::WinCalcFrameRect(hWndFrame, &vRect, TRUE);
1508 nWidthFrameDelta = ((vRect.xLeft - vFRect.xLeft) + (vFRect.xRight - vRect.xRight));
1509 nHeightFrameDelta = ((vRect.yBottom - vFRect.yBottom) + (vFRect.yTop - vRect.yTop));
1510 nWidthFrame = vFRect.xRight - vFRect.xLeft;
1511 nHeightFrame = vFRect.yTop - vFRect.yBottom;
1512
1513 if (nWidth == vFRect.xRight - vFRect.xLeft &&
1514 nHeight == vFRect.yTop - vFRect.yBottom)
1515 {
1516 //
1517 // In this case the caller is not aware of OS/2's need to size both
1518 // the frame and it's client and is really only moving the window,
1519 // not resizeing it. So move the frame, and back off the sizes
1520 // for a proper client fit.
1521 //
1522 ::WinSetWindowPos( hWndFrame
1523 ,HWND_TOP
1524 ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
1525 ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
1526 ,(LONG)0
1527 ,(LONG)0
1528 ,SWP_MOVE
1529 );
1530 nX += (vRect.xLeft - vFRect.xLeft);
1531 nY += (vRect.yBottom - vFRect.yBottom);
1532 nWidth -= nWidthFrameDelta;
1533 nHeight -= nHeightFrameDelta;
1534 }
1535 else
1536 {
1537 if (nWidth > nWidthFrame - nHeightFrameDelta ||
1538 nHeight > nHeightFrame - nHeightFrameDelta)
1539 {
1540 ::WinSetWindowPos( hWndFrame
1541 ,HWND_TOP
1542 ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
1543 ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
1544 ,(LONG)nWidth + nWidthFrameDelta
1545 ,(LONG)nHeight + nHeightFrameDelta
1546 ,SWP_MOVE | SWP_SIZE
1547 );
1548 }
1549 }
1550 }
1551
1552 ::WinSetWindowPos( GetHwnd()
1553 ,HWND_TOP
1554 ,(LONG)nX
1555 ,(LONG)nY
1556 ,(LONG)nWidth
1557 ,(LONG)nHeight
1558 ,SWP_SIZE | SWP_MOVE
1559 );
1560 if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0)
1561 //
1562 // Uninitialized
1563 //
1564 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1565 else
1566 {
1567 int nYDiff = m_vWinSwp.cy - nHeight;
1568
1569 //
1570 // Handle resizing of scrolled windows. The target or window to
1571 // be scrolled is the owner (gets the scroll notifications). The
1572 // parent is usually the parent frame of the scrolled panel window.
1573 // In order to show the scrollbars the target window will be shrunk
1574 // by the size of the scroll bar widths and moved in the X and Y
1575 // directon. That value will be computed as part of the diff for
1576 // moving the children. Everytime the window is sized the
1577 // toplevel OnSize is going to resize the panel to fit the client
1578 // or the whole sizer and will need to me resized. This will send
1579 // a WM_SIZE out which will be intercepted by the ScrollHelper
1580 // which will cause the scrollbars to be displayed via the SetScrollbar
1581 // call in CWindow.
1582 //
1583 if (IsKindOf(CLASSINFO(wxScrolledWindow)))
1584 {
1585 int nAdjustWidth = 0;
1586 int nAdjustHeight = 0;
1587 int nHSBHeight = wxSystemSettingsNative::GetMetric(wxSYS_HSCROLL_Y,
1588 this);
1589 int nVSBWidth = wxSystemSettingsNative::GetMetric(wxSYS_VSCROLL_X,
1590 this);
1591 SWP vSwpScroll;
1592
1593 if (GetScrollBarHorz() == NULLHANDLE ||
1594 !WinIsWindowShowing(GetScrollBarHorz()))
1595 nAdjustHeight = 0L;
1596 else
1597 nAdjustHeight = nHSBHeight;
1598 if (GetScrollBarVert() == NULLHANDLE ||
1599 !WinIsWindowShowing(GetScrollBarVert()))
1600 nAdjustWidth = 0L;
1601 else
1602 nAdjustWidth = nVSBWidth;
1603 ::WinQueryWindowPos(GetHwnd(), &vSwpScroll);
1604 ::WinSetWindowPos( GetHwnd()
1605 ,HWND_TOP
1606 ,vSwpScroll.x
1607 ,vSwpScroll.y + nAdjustHeight
1608 ,vSwpScroll.cx - nAdjustWidth
1609 ,vSwpScroll.cy - nAdjustHeight
1610 ,SWP_MOVE | SWP_SIZE
1611 );
1612 nYDiff -= nAdjustHeight;
1613 }
1614 MoveChildren(nYDiff);
1615 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1616 }
1617 #if 0
1618 // FIXME: By my logic, the next line should be needed as it moves child
1619 // windows when resizing the parent (see comment at beginning of
1620 // function). However, this seems to cause lots of problems. At
1621 // least, e.g. the grid sample almost works with this line
1622 // commented out but crashes badly with it.
1623 MoveChildren(nHeightDelta);
1624 #endif
1625 } // end of wxWindowOS2::DoMoveWindow
1626
1627 //
1628 // Set the size of the window: if the dimensions are positive, just use them,
1629 // but if any of them is equal to -1, it means that we must find the value for
1630 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1631 // which case -1 is a valid value for x and y)
1632 //
1633 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1634 // the width/height to best suit our contents, otherwise we reuse the current
1635 // width/height
1636 //
1637 void wxWindowOS2::DoSetSize( int nX,
1638 int nY,
1639 int nWidth,
1640 int nHeight,
1641 int nSizeFlags )
1642 {
1643 //
1644 // Get the current size and position...
1645 //
1646 int nCurrentX;
1647 int nCurrentY;
1648 int nCurrentWidth;
1649 int nCurrentHeight;
1650 wxSize vSize = wxDefaultSize;
1651
1652 GetPosition(&nCurrentX, &nCurrentY);
1653 GetSize(&nCurrentWidth, &nCurrentHeight);
1654
1655 //
1656 // ... and don't do anything (avoiding flicker) if it's already ok
1657 //
1658 //
1659 // Must convert Y coords to test for equality under OS/2
1660 //
1661 int nY2 = nY;
1662
1663 if (nX == nCurrentX && nY2 == nCurrentY &&
1664 nWidth == nCurrentWidth && nHeight == nCurrentHeight)
1665 {
1666 return;
1667 }
1668
1669 if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1670 nX = nCurrentX;
1671 if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1672 nY = nCurrentY;
1673
1674 AdjustForParentClientOrigin(nX, nY, nSizeFlags);
1675
1676 if (nWidth == wxDefaultCoord)
1677 {
1678 if (nSizeFlags & wxSIZE_AUTO_WIDTH)
1679 {
1680 vSize = DoGetBestSize();
1681 nWidth = vSize.x;
1682 }
1683 else
1684 {
1685 //
1686 // Just take the current one
1687 //
1688 nWidth = nCurrentWidth;
1689 }
1690 }
1691
1692 if (nHeight == wxDefaultCoord)
1693 {
1694 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
1695 {
1696 if (vSize.x == wxDefaultCoord)
1697 {
1698 vSize = DoGetBestSize();
1699 }
1700 nHeight = vSize.y;
1701 }
1702 else
1703 {
1704 // just take the current one
1705 nHeight = nCurrentHeight;
1706 }
1707 }
1708
1709 DoMoveWindow( nX, nY, nWidth, nHeight );
1710 } // end of wxWindowOS2::DoSetSize
1711
1712 void wxWindowOS2::DoSetClientSize( int nWidth,
1713 int nHeight )
1714 {
1715 POINTL vPoint;
1716 int nActualWidth;
1717 int nActualHeight;
1718 wxWindow* pParent = (wxWindow*)GetParent();
1719 HWND hParentWnd = (HWND)0;
1720
1721 if (pParent)
1722 hParentWnd = (HWND)pParent->GetHWND();
1723
1724 if (IsKindOf(CLASSINFO(wxFrame)))
1725 {
1726 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1727 HWND hFrame = pFrame->GetFrame();
1728 RECTL vRect;
1729 RECTL vRect2;
1730 RECTL vRect3;
1731
1732 ::WinQueryWindowRect(GetHwnd(), &vRect2);
1733 ::WinQueryWindowRect(hFrame, &vRect);
1734 ::WinQueryWindowRect(hParentWnd, &vRect3);
1735 nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
1736 nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
1737
1738 vPoint.x = vRect2.xLeft;
1739 vPoint.y = vRect2.yBottom;
1740 if (pParent)
1741 {
1742 vPoint.x -= vRect3.xLeft;
1743 vPoint.y -= vRect3.yBottom;
1744 }
1745 }
1746 else
1747 {
1748 int nX;
1749 int nY;
1750
1751 GetPosition(&nX, &nY);
1752 nActualWidth = nWidth;
1753 nActualHeight = nHeight;
1754
1755 vPoint.x = nX;
1756 vPoint.y = nY;
1757 }
1758 DoMoveWindow( vPoint.x, vPoint.y, nActualWidth, nActualHeight );
1759
1760 wxSize size( nWidth, nHeight );
1761 wxSizeEvent vEvent( size, m_windowId );
1762 vEvent.SetEventObject(this);
1763 GetEventHandler()->ProcessEvent(vEvent);
1764 } // end of wxWindowOS2::DoSetClientSize
1765
1766 // ---------------------------------------------------------------------------
1767 // text metrics
1768 // ---------------------------------------------------------------------------
1769
1770 int wxWindowOS2::GetCharHeight() const
1771 {
1772 HPS hPs;
1773 FONTMETRICS vFontMetrics;
1774
1775 hPs = ::WinGetPS(GetHwnd());
1776
1777 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
1778 {
1779 ::WinReleasePS(hPs);
1780 return (0);
1781 }
1782 ::WinReleasePS(hPs);
1783 return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender);
1784 } // end of wxWindowOS2::GetCharHeight
1785
1786 int wxWindowOS2::GetCharWidth() const
1787 {
1788 HPS hPs;
1789 FONTMETRICS vFontMetrics;
1790
1791 hPs = ::WinGetPS(GetHwnd());
1792
1793 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
1794 {
1795 ::WinReleasePS(hPs);
1796 return (0);
1797 }
1798 ::WinReleasePS(hPs);
1799 return(vFontMetrics.lAveCharWidth);
1800 } // end of wxWindowOS2::GetCharWidth
1801
1802 void wxWindowOS2::GetTextExtent( const wxString& rString,
1803 int* pX,
1804 int* pY,
1805 int* pDescent,
1806 int* pExternalLeading,
1807 const wxFont* WXUNUSED(pTheFont) ) const
1808 {
1809 POINTL avPoint[TXTBOX_COUNT];
1810 POINTL vPtMin;
1811 POINTL vPtMax;
1812 int i;
1813 int l;
1814 FONTMETRICS vFM; // metrics structure
1815 BOOL bRc = FALSE;
1816 char* pStr;
1817 HPS hPS;
1818
1819 hPS = ::WinGetPS(GetHwnd());
1820
1821 l = rString.length();
1822 if (l > 0L)
1823 {
1824 pStr = (PCH)rString.c_str();
1825
1826 //
1827 // In world coordinates.
1828 //
1829 bRc = ::GpiQueryTextBox( hPS,
1830 l,
1831 pStr,
1832 TXTBOX_COUNT,// return maximum information
1833 avPoint // array of coordinates points
1834 );
1835 if (bRc)
1836 {
1837 vPtMin.x = avPoint[0].x;
1838 vPtMax.x = avPoint[0].x;
1839 vPtMin.y = avPoint[0].y;
1840 vPtMax.y = avPoint[0].y;
1841 for (i = 1; i < 4; i++)
1842 {
1843 if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
1844 if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
1845 if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
1846 if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
1847 }
1848 bRc = ::GpiQueryFontMetrics( hPS
1849 ,sizeof(FONTMETRICS)
1850 ,&vFM
1851 );
1852 if (!bRc)
1853 {
1854 vPtMin.x = 0;
1855 vPtMin.y = 0;
1856 vPtMax.x = 0;
1857 vPtMax.y = 0;
1858 }
1859 }
1860 else
1861 {
1862 vPtMin.x = 0;
1863 vPtMin.y = 0;
1864 vPtMax.x = 0;
1865 vPtMax.y = 0;
1866 }
1867 }
1868 else
1869 {
1870 vPtMin.x = 0;
1871 vPtMin.y = 0;
1872 vPtMax.x = 0;
1873 vPtMax.y = 0;
1874 }
1875 if (pX)
1876 *pX = (vPtMax.x - vPtMin.x + 1);
1877 if (pY)
1878 *pY = (vPtMax.y - vPtMin.y + 1);
1879 if (pDescent)
1880 {
1881 if (bRc)
1882 *pDescent = vFM.lMaxDescender;
1883 else
1884 *pDescent = 0;
1885 }
1886 if (pExternalLeading)
1887 {
1888 if (bRc)
1889 *pExternalLeading = vFM.lExternalLeading;
1890 else
1891 *pExternalLeading = 0;
1892 }
1893 ::WinReleasePS(hPS);
1894 } // end of wxWindow::GetTextExtent
1895
1896 bool wxWindowOS2::IsMouseInWindow() const
1897 {
1898 //
1899 // Get the mouse position
1900 POINTL vPt;
1901
1902 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
1903
1904 //
1905 // Find the window which currently has the cursor and go up the window
1906 // chain until we find this window - or exhaust it
1907 //
1908 HWND hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPt, TRUE);
1909
1910 while (hWnd && (hWnd != GetHwnd()))
1911 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
1912
1913 return hWnd != NULL;
1914 } // end of wxWindowOS2::IsMouseInWindow
1915
1916
1917 // ---------------------------------------------------------------------------
1918 // popup menu
1919 // ---------------------------------------------------------------------------
1920 //
1921 #if wxUSE_MENUS_NATIVE
1922 bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
1923 {
1924 HWND hWndOwner = GetHwnd();
1925 HWND hWndParent = GetHwnd();
1926 HWND hMenu = GetHmenuOf(pMenu);
1927 bool bIsWaiting = true;
1928 int nHeight;
1929
1930 // Protect against recursion
1931 if (wxCurrentPopupMenu)
1932 return false;
1933
1934 pMenu->SetInvokingWindow(this);
1935 pMenu->UpdateUI();
1936
1937 if ( nX == -1 && nY == -1 )
1938 {
1939 wxPoint mouse = wxGetMousePosition();
1940 nX = mouse.x; nY = mouse.y;
1941 }
1942 else
1943 {
1944 DoClientToScreen( &nX
1945 ,&nY
1946 );
1947 DoGetSize(0,&nHeight);
1948 nY = nHeight - nY;
1949 }
1950 wxCurrentPopupMenu = pMenu;
1951
1952 ::WinPopupMenu( hWndParent
1953 ,hWndOwner
1954 ,hMenu
1955 ,nX
1956 ,nY
1957 ,0L
1958 ,PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 | PU_KEYBOARD
1959 );
1960
1961 while(bIsWaiting)
1962 {
1963 QMSG vMsg;
1964
1965 ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
1966 if (vMsg.msg == WM_COMMAND)
1967 bIsWaiting = false;
1968 ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
1969 }
1970
1971 wxCurrentPopupMenu = NULL;
1972 pMenu->SetInvokingWindow(NULL);
1973 return true;
1974 } // end of wxWindowOS2::DoPopupMenu
1975 #endif // wxUSE_MENUS_NATIVE
1976
1977 // ===========================================================================
1978 // pre/post message processing
1979 // ===========================================================================
1980
1981 MRESULT wxWindowOS2::OS2DefWindowProc( WXUINT uMsg,
1982 WXWPARAM wParam,
1983 WXLPARAM lParam )
1984 {
1985 if (m_fnOldWndProc)
1986 return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
1987 else
1988 return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
1989 } // end of wxWindowOS2::OS2DefWindowProc
1990
1991 bool wxWindowOS2::OS2ProcessMessage( WXMSG* pMsg )
1992 {
1993 // wxUniversal implements tab traversal itself
1994 #ifndef __WXUNIVERSAL__
1995 QMSG* pQMsg = (QMSG*)pMsg;
1996
1997 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
1998 {
1999 //
2000 // Intercept dialog navigation keys
2001 //
2002 bool bProcess = true;
2003 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
2004
2005 if (uKeyFlags & KC_KEYUP)
2006 bProcess = false;
2007
2008 if (uKeyFlags & KC_ALT)
2009 bProcess = false;
2010
2011 if (!(uKeyFlags & KC_VIRTUALKEY))
2012 bProcess = false;
2013
2014 if (bProcess)
2015 {
2016 bool bCtrlDown = IsCtrlDown();
2017 bool bShiftDown = IsShiftDown();
2018
2019 //
2020 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
2021 // don't process it if it's the case (except for Ctrl-Tab/Enter
2022 // combinations which are always processed)
2023 //
2024 ULONG ulDlgCode = 0;
2025
2026 if (!bCtrlDown)
2027 {
2028 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
2029 }
2030
2031 bool bForward = true;
2032 bool bWindowChange = false;
2033
2034 switch (SHORT2FROMMP(pQMsg->mp2))
2035 {
2036 //
2037 // Going to make certain assumptions about specific types of controls
2038 // here, so we may have to alter some things later if they prove invalid
2039 //
2040 case VK_TAB:
2041 //
2042 // Shift tabl will always be a nav-key but tabs may be wanted
2043 //
2044 if (!bShiftDown)
2045 {
2046 bProcess = false;
2047 }
2048 else
2049 {
2050 //
2051 // Entry Fields want tabs for themselve usually
2052 //
2053 switch (ulDlgCode)
2054 {
2055 case DLGC_ENTRYFIELD:
2056 case DLGC_MLE:
2057 bProcess = true;
2058 break;
2059
2060 default:
2061 bProcess = false;
2062 }
2063
2064 //
2065 // Ctrl-Tab cycles thru notebook pages
2066 //
2067 bWindowChange = bCtrlDown;
2068 bForward = !bShiftDown;
2069 }
2070 break;
2071
2072 case VK_UP:
2073 case VK_LEFT:
2074 if (bCtrlDown)
2075 bProcess = false;
2076 else
2077 bForward = false;
2078 break;
2079
2080 case VK_DOWN:
2081 case VK_RIGHT:
2082 if (bCtrlDown)
2083 bProcess = false;
2084 break;
2085
2086 case VK_ENTER:
2087 {
2088 if (bCtrlDown)
2089 {
2090 //
2091 // ctrl-enter is not processed
2092 //
2093 return false;
2094 }
2095 else if (ulDlgCode & DLGC_BUTTON)
2096 {
2097 //
2098 // buttons want process Enter themselevs
2099 //
2100 bProcess = false;
2101 }
2102 else
2103 {
2104 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
2105 ,wxButton
2106 );
2107
2108 if (pBtn && pBtn->IsEnabled())
2109 {
2110 //
2111 // If we do have a default button, do press it
2112 //
2113 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
2114 return true;
2115 }
2116 else if (!IsTopLevel())
2117 {
2118 //
2119 // if not a top level window, let parent
2120 // handle it
2121 //
2122 return false;
2123 }
2124 // else: but if it does not it makes sense to make
2125 // it work like a TAB - and that's what we do.
2126 // Note that Ctrl-Enter always works this way.
2127 }
2128 }
2129 break;
2130
2131 default:
2132 bProcess = false;
2133 }
2134
2135 if (bProcess)
2136 {
2137 wxNavigationKeyEvent vEvent;
2138
2139 vEvent.SetDirection(bForward);
2140 vEvent.SetWindowChange(bWindowChange);
2141 vEvent.SetEventObject(this);
2142
2143 if (GetEventHandler()->ProcessEvent(vEvent))
2144 {
2145 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2146
2147 if (pBtn)
2148 {
2149 //
2150 // The button which has focus should be default
2151 //
2152 pBtn->SetDefault();
2153 }
2154 return true;
2155 }
2156 }
2157 }
2158 //
2159 // Let Dialogs process
2160 //
2161 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
2162 return true;
2163 }
2164 #else
2165 pMsg = pMsg; // just shut up the compiler
2166 #endif // __WXUNIVERSAL__
2167
2168 return false;
2169 } // end of wxWindowOS2::OS2ProcessMessage
2170
2171 bool wxWindowOS2::OS2TranslateMessage( WXMSG* pMsg )
2172 {
2173 #if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
2174 return m_acceleratorTable.Translate(m_hWnd, pMsg);
2175 #else
2176 pMsg = pMsg;
2177 return false;
2178 #endif //wxUSE_ACCEL
2179 } // end of wxWindowOS2::OS2TranslateMessage
2180
2181 bool wxWindowOS2::OS2ShouldPreProcessMessage( WXMSG* WXUNUSED(pMsg) )
2182 {
2183 // preprocess all messages by default
2184 return true;
2185 } // end of wxWindowOS2::OS2ShouldPreProcessMessage
2186
2187 // ---------------------------------------------------------------------------
2188 // message params unpackers
2189 // ---------------------------------------------------------------------------
2190
2191 void wxWindowOS2::UnpackCommand(
2192 WXWPARAM wParam
2193 , WXLPARAM lParam
2194 , WORD* pId
2195 , WXHWND* phWnd
2196 , WORD* pCmd
2197 )
2198 {
2199 *pId = LOWORD(wParam);
2200 *phWnd = NULL; // or may be GetHWND() ?
2201 *pCmd = LOWORD(lParam);
2202 } // end of wxWindowOS2::UnpackCommand
2203
2204 void wxWindowOS2::UnpackActivate(
2205 WXWPARAM wParam
2206 , WXLPARAM lParam
2207 , WXWORD* pState
2208 , WXHWND* phWnd
2209 )
2210 {
2211 *pState = LOWORD(wParam);
2212 *phWnd = (WXHWND)lParam;
2213 } // end of wxWindowOS2::UnpackActivate
2214
2215 void wxWindowOS2::UnpackScroll(
2216 WXWPARAM wParam
2217 , WXLPARAM lParam
2218 , WXWORD* pCode
2219 , WXWORD* pPos
2220 , WXHWND* phWnd
2221 )
2222 {
2223 ULONG ulId;
2224 HWND hWnd;
2225
2226 ulId = (ULONG)LONGFROMMP(wParam);
2227 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2228 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2229 *phWnd = NULLHANDLE;
2230 else
2231 *phWnd = hWnd;
2232
2233 *pPos = SHORT1FROMMP(lParam);
2234 *pCode = SHORT2FROMMP(lParam);
2235 } // end of wxWindowOS2::UnpackScroll
2236
2237 void wxWindowOS2::UnpackMenuSelect(
2238 WXWPARAM wParam
2239 , WXLPARAM lParam
2240 , WXWORD* pItem
2241 , WXWORD* pFlags
2242 , WXHMENU* phMenu
2243 )
2244 {
2245 *pItem = (WXWORD)LOWORD(wParam);
2246 *pFlags = HIWORD(wParam);
2247 *phMenu = (WXHMENU)lParam;
2248 } // end of wxWindowOS2::UnpackMenuSelect
2249
2250 // ---------------------------------------------------------------------------
2251 // Main wxWidgets window proc and the window proc for wxWindow
2252 // ---------------------------------------------------------------------------
2253
2254 //
2255 // Hook for new window just as it's being created, when the window isn't yet
2256 // associated with the handle
2257 //
2258 wxWindowOS2* wxWndHook = NULL;
2259
2260 //
2261 // Main window proc
2262 //
2263 MRESULT EXPENTRY wxWndProc(
2264 HWND hWnd
2265 , ULONG ulMsg
2266 , MPARAM wParam
2267 , MPARAM lParam
2268 )
2269 {
2270 wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
2271
2272 //
2273 // When we get the first message for the HWND we just created, we associate
2274 // it with wxWindow stored in wxWndHook
2275 //
2276 if (!pWnd && wxWndHook)
2277 {
2278 wxAssociateWinWithHandle(hWnd, wxWndHook);
2279 pWnd = wxWndHook;
2280 wxWndHook = NULL;
2281 pWnd->SetHWND((WXHWND)hWnd);
2282 }
2283
2284 MRESULT rc = (MRESULT)0;
2285
2286
2287 //
2288 // Stop right here if we don't have a valid handle in our wxWindow object.
2289 //
2290 if (pWnd && !pWnd->GetHWND())
2291 {
2292 pWnd->SetHWND((WXHWND) hWnd);
2293 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2294 pWnd->SetHWND(0);
2295 }
2296 else
2297 {
2298 if (pWnd)
2299 {
2300 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
2301 if ( (pWnd->GetScrollBarHorz() != NULLHANDLE ||
2302 pWnd->GetScrollBarVert() != NULLHANDLE) &&
2303 ulMsg == WM_PAINT)
2304 {
2305 if (pWnd->GetScrollBarHorz() != NULLHANDLE)
2306 ::WinInvalidateRect(pWnd->GetScrollBarHorz(), NULL, TRUE);
2307 if (pWnd->GetScrollBarVert() != NULLHANDLE)
2308 ::WinInvalidateRect(pWnd->GetScrollBarVert(), NULL, TRUE);
2309 }
2310 }
2311 else
2312 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
2313 }
2314
2315 return rc;
2316 } // end of wxWndProc
2317
2318 //
2319 // We will add (or delete) messages we need to handle at this default
2320 // level as we go
2321 //
2322 MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
2323 WXWPARAM wParam,
2324 WXLPARAM lParam )
2325 {
2326 //
2327 // Did we process the uMsg?
2328 //
2329 bool bProcessed = false;
2330 MRESULT mResult;
2331
2332 //
2333 // For most messages we should return 0 when we do process the message
2334 //
2335 mResult = (MRESULT)0;
2336
2337 switch (uMsg)
2338 {
2339 case WM_CREATE:
2340 {
2341 bool bMayCreate;
2342
2343 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2344 ,&bMayCreate
2345 );
2346 if (bProcessed)
2347 {
2348 //
2349 // Return 0 to bAllow window creation
2350 //
2351 mResult = (MRESULT)(bMayCreate ? 0 : -1);
2352 }
2353 }
2354 break;
2355
2356 case WM_DESTROY:
2357 HandleDestroy();
2358 bProcessed = true;
2359 break;
2360
2361 case WM_MOVE:
2362 bProcessed = HandleMove( LOWORD(lParam)
2363 ,HIWORD(lParam)
2364 );
2365 break;
2366
2367 case WM_SIZE:
2368 bProcessed = HandleSize( LOWORD(lParam)
2369 ,HIWORD(lParam)
2370 ,(WXUINT)wParam
2371 );
2372 break;
2373
2374 case WM_WINDOWPOSCHANGED:
2375
2376 //
2377 // Dialogs under OS/2 do not get WM_SIZE events at all.
2378 // Instead they get this, which can function much like WM_SIZE
2379 // PSWP contains the new sizes and positioning, PSWP+1 the old
2380 // We use this because ADJUSTWINDOWPOS comes BEFORE the new
2381 // position is added and our auto layout does a WinQueryWindowRect
2382 // to get the CURRENT client size. That is the size used to position
2383 // child controls, so we need to already be sized
2384 // in order to get the child controls positoned properly.
2385 //
2386 if (IsKindOf(CLASSINFO(wxDialog)) || IsKindOf(CLASSINFO(wxFrame)))
2387 {
2388 PSWP pSwp = (PSWP)PVOIDFROMMP(wParam);
2389 PSWP pSwp2 = pSwp++;
2390
2391 if (!(pSwp->cx == pSwp2->cx &&
2392 pSwp->cy == pSwp2->cy))
2393 bProcessed = HandleSize( pSwp->cx
2394 ,pSwp->cy
2395 ,(WXUINT)lParam
2396 );
2397 if (IsKindOf(CLASSINFO(wxFrame)))
2398 {
2399 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
2400
2401 if (pFrame)
2402 {
2403 if (pFrame->GetStatusBar())
2404 pFrame->PositionStatusBar();
2405 if (pFrame->GetToolBar())
2406 pFrame->PositionToolBar();
2407 }
2408 }
2409 }
2410 break;
2411
2412 case WM_ACTIVATE:
2413 {
2414 WXWORD wState;
2415 WXHWND hWnd;
2416
2417 UnpackActivate( wParam
2418 ,lParam
2419 ,&wState
2420 ,&hWnd
2421 );
2422
2423 bProcessed = HandleActivate( wState
2424 ,(WXHWND)hWnd
2425 );
2426 bProcessed = false;
2427 }
2428 break;
2429
2430 case WM_SETFOCUS:
2431 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2432 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2433 else
2434 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
2435 break;
2436
2437 case WM_PAINT:
2438 bProcessed = HandlePaint();
2439 break;
2440
2441 case WM_CLOSE:
2442 //
2443 // Don't let the DefWindowProc() destroy our window - we'll do it
2444 // ourselves in ~wxWindow
2445 //
2446 bProcessed = true;
2447 mResult = (MRESULT)TRUE;
2448 break;
2449
2450 case WM_SHOW:
2451 bProcessed = HandleShow(wParam != 0, (int)lParam);
2452 break;
2453
2454 //
2455 // Under OS2 PM Joysticks are treated just like mouse events
2456 // The "Motion" events will be prevelent in joysticks
2457 //
2458 case WM_MOUSEMOVE:
2459 case WM_BUTTON1DOWN:
2460 case WM_BUTTON1UP:
2461 case WM_BUTTON1DBLCLK:
2462 case WM_BUTTON1MOTIONEND:
2463 case WM_BUTTON1MOTIONSTART:
2464 case WM_BUTTON2DOWN:
2465 case WM_BUTTON2UP:
2466 case WM_BUTTON2DBLCLK:
2467 case WM_BUTTON2MOTIONEND:
2468 case WM_BUTTON2MOTIONSTART:
2469 case WM_BUTTON3DOWN:
2470 case WM_BUTTON3UP:
2471 case WM_BUTTON3DBLCLK:
2472 case WM_BUTTON3MOTIONEND:
2473 case WM_BUTTON3MOTIONSTART:
2474 {
2475 if (uMsg == WM_BUTTON1DOWN && AcceptsFocus())
2476 SetFocus();
2477
2478 short nX = LOWORD(wParam);
2479 short nY = HIWORD(wParam);
2480
2481 //
2482 // Redirect the event to a static control if necessary
2483 //
2484 if (this == GetCapture())
2485 {
2486 bProcessed = HandleMouseEvent( uMsg
2487 ,nX
2488 ,nY
2489 ,(WXUINT)SHORT2FROMMP(lParam)
2490 );
2491 }
2492 else
2493 {
2494 wxWindow* pWin = FindWindowForMouseEvent( this
2495 ,&nX
2496 ,&nY
2497 );
2498 if (!pWin->IsOfStandardClass())
2499 {
2500 if (uMsg == WM_BUTTON1DOWN && pWin->AcceptsFocus() )
2501 pWin->SetFocus();
2502 }
2503 bProcessed = pWin->HandleMouseEvent( uMsg
2504 ,nX
2505 ,nY
2506 ,(WXUINT)SHORT2FROMMP(lParam)
2507 );
2508 }
2509 }
2510 break;
2511
2512 case WM_SYSCOMMAND:
2513 bProcessed = HandleSysCommand(wParam, lParam);
2514 break;
2515
2516 case WM_COMMAND:
2517 {
2518 WORD id, cmd;
2519 WXHWND hwnd;
2520 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2521
2522 bProcessed = HandleCommand(id, cmd, hwnd);
2523 }
2524 break;
2525
2526 //
2527 // For these messages we must return TRUE if process the message
2528 //
2529 case WM_DRAWITEM:
2530 case WM_MEASUREITEM:
2531 {
2532 int nIdCtrl = (UINT)wParam;
2533
2534 if ( uMsg == WM_DRAWITEM )
2535 {
2536 bProcessed = OS2OnDrawItem(nIdCtrl,
2537 (WXDRAWITEMSTRUCT *)lParam);
2538 }
2539 else
2540 {
2541 return MRFROMLONG(OS2OnMeasureItem( nIdCtrl
2542 ,(WXMEASUREITEMSTRUCT *)lParam
2543 ));
2544 }
2545
2546 if ( bProcessed )
2547 mResult = (MRESULT)TRUE;
2548 }
2549 break;
2550
2551 case WM_QUERYDLGCODE:
2552 if (!IsOfStandardClass())
2553 {
2554 if ( m_lDlgCode )
2555 {
2556 mResult = (MRESULT)m_lDlgCode;
2557 bProcessed = true;
2558 }
2559 }
2560 //
2561 //else: get the dlg code from the DefWindowProc()
2562 //
2563 break;
2564
2565 //
2566 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2567 // and key-down events are obtained from the WM_CHAR params.
2568 //
2569 case WM_CHAR:
2570 {
2571 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
2572
2573 if (uKeyFlags & KC_KEYUP)
2574 {
2575 //TODO: check if the cast to WXWORD isn't causing trouble
2576 bProcessed = HandleKeyUp(wParam, lParam);
2577 break;
2578 }
2579 else // keydown event
2580 {
2581 m_bLastKeydownProcessed = false;
2582 //
2583 // If this has been processed by an event handler,
2584 // return 0 now (we've handled it). DON't RETURN
2585 // we still need to process further
2586 //
2587 m_bLastKeydownProcessed = HandleKeyDown(wParam, lParam);
2588 if (uKeyFlags & KC_VIRTUALKEY)
2589 {
2590 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2591
2592 //
2593 // We consider these message "not interesting" to OnChar
2594 //
2595 switch(uVk)
2596 {
2597 case VK_SHIFT:
2598 case VK_CTRL:
2599 case VK_MENU:
2600 case VK_CAPSLOCK:
2601 case VK_NUMLOCK:
2602 case VK_SCRLLOCK:
2603 bProcessed = true;
2604 break;
2605
2606 // Avoid duplicate messages to OnChar for these ASCII keys: they
2607 // will be translated by TranslateMessage() and received in WM_CHAR
2608 case VK_ESC:
2609 case VK_ENTER:
2610 case VK_BACKSPACE:
2611 case VK_TAB:
2612 // But set processed to false, not true to still pass them to
2613 // the control's default window proc - otherwise built-in
2614 // keyboard handling won't work
2615 bProcessed = false;
2616 break;
2617
2618 default:
2619 bProcessed = HandleChar(wParam, lParam);
2620 }
2621 break;
2622 }
2623 else // WM_CHAR -- Always an ASCII character
2624 {
2625 if (m_bLastKeydownProcessed)
2626 {
2627 //
2628 // The key was handled in the EVT_KEY_DOWN and handling
2629 // a key in an EVT_KEY_DOWN handler is meant, by
2630 // design, to prevent EVT_CHARs from happening
2631 //
2632 m_bLastKeydownProcessed = false;
2633 bProcessed = true;
2634 }
2635 else // do generate a CHAR event
2636 {
2637 bProcessed = HandleChar(wParam, lParam, true);
2638 break;
2639 }
2640 }
2641 }
2642 }
2643
2644 case WM_HSCROLL:
2645 case WM_VSCROLL:
2646 {
2647 WXWORD wCode;
2648 WXWORD wPos;
2649 WXHWND hWnd;
2650 UnpackScroll( wParam
2651 ,lParam
2652 ,&wCode
2653 ,&wPos
2654 ,&hWnd
2655 );
2656
2657 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2658 : wxVERTICAL
2659 ,wCode
2660 ,wPos
2661 ,hWnd
2662 );
2663 }
2664 break;
2665
2666 case WM_CONTROL:
2667 switch(SHORT2FROMMP(wParam))
2668 {
2669 case BN_PAINT:
2670 {
2671 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2672 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2673
2674 if (!pWin)
2675 {
2676 bProcessed = false;
2677 break;
2678 }
2679 if (pWin->IsKindOf(CLASSINFO(wxBitmapButton)))
2680 {
2681 wxBitmapButton* pBitmapButton = wxDynamicCast(pWin, wxBitmapButton);
2682
2683 pBitmapButton->OS2OnDraw((WXDRAWITEMSTRUCT *)lParam);
2684 }
2685 return 0;
2686 }
2687 // break;
2688
2689 case BKN_PAGESELECTEDPENDING:
2690 {
2691 PPAGESELECTNOTIFY pPage = (PPAGESELECTNOTIFY)lParam;
2692
2693 if ((pPage->ulPageIdNew != pPage->ulPageIdCur) &&
2694 (pPage->ulPageIdNew > 0L && pPage->ulPageIdCur > 0L))
2695 {
2696 wxWindowOS2* pWin = wxFindWinFromHandle(pPage->hwndBook);
2697 wxNotebookEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
2698 ,(int)SHORT1FROMMP(wParam)
2699 ,(int)pPage->ulPageIdNew
2700 ,(int)pPage->ulPageIdCur
2701 );
2702 if (!pWin)
2703 {
2704 bProcessed = false;
2705 break;
2706 }
2707 if (pWin->IsKindOf(CLASSINFO(wxNotebook)))
2708 {
2709 wxNotebook* pNotebook = wxDynamicCast(pWin, wxNotebook);
2710
2711 vEvent.SetEventObject(pWin);
2712 pNotebook->OnSelChange(vEvent);
2713 bProcessed = true;
2714 }
2715 else
2716 bProcessed = false;
2717 }
2718 else
2719 bProcessed = false;
2720 }
2721 break;
2722
2723 case BN_CLICKED: // Dups as LN_SELECT and CBN_LBSELECT
2724 {
2725 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2726 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2727
2728 if (!pWin)
2729 {
2730 bProcessed = false;
2731 break;
2732 }
2733 //
2734 // Simulate a WM_COMMAND here, as wxWidgets expects all control
2735 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2736 //
2737 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
2738 {
2739 wxRadioBox* pRadioBox = wxDynamicCast(pWin, wxRadioBox);
2740
2741 pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2742 ,(WXWORD)SHORT1FROMMP(wParam)
2743 );
2744 }
2745 if (pWin->IsKindOf(CLASSINFO(wxRadioButton)))
2746 {
2747 wxRadioButton* pRadioButton = wxDynamicCast(pWin, wxRadioButton);
2748
2749 pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2750 ,(WXWORD)SHORT1FROMMP(wParam)
2751 );
2752 }
2753 if (pWin->IsKindOf(CLASSINFO(wxCheckBox)))
2754 {
2755 wxCheckBox* pCheckBox = wxDynamicCast(pWin, wxCheckBox);
2756
2757 pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2758 ,(WXWORD)SHORT1FROMMP(wParam)
2759 );
2760 }
2761 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2762 {
2763 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2764
2765 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2766 ,(WXWORD)SHORT1FROMMP(wParam)
2767 );
2768 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2769 Refresh();
2770 }
2771 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2772 {
2773 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2774
2775 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2776 ,(WXWORD)SHORT1FROMMP(wParam)
2777 );
2778 }
2779 return 0;
2780 }
2781 // break;
2782
2783 case LN_ENTER: /* dups as CBN_EFCHANGE */
2784 {
2785 HWND hWnd = HWNDFROMMP(lParam);
2786 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2787
2788 if (!pWin)
2789 {
2790 bProcessed = false;
2791 break;
2792 }
2793 //
2794 // Simulate a WM_COMMAND here, as wxWidgets expects all control
2795 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2796 //
2797 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2798 {
2799 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2800
2801 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2802 ,(WXWORD)SHORT1FROMMP(wParam)
2803 );
2804 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2805 Refresh();
2806
2807 }
2808 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2809 {
2810 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2811
2812 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2813 ,(WXWORD)SHORT1FROMMP(wParam)
2814 );
2815 }
2816 return 0;
2817 }
2818 // break;
2819
2820 case SPBN_UPARROW:
2821 case SPBN_DOWNARROW:
2822 case SPBN_CHANGE:
2823 {
2824 char zVal[10];
2825 long lVal;
2826
2827 ::WinSendMsg( HWNDFROMMP(lParam)
2828 ,SPBM_QUERYVALUE
2829 ,&zVal[0]
2830 ,MPFROM2SHORT( (USHORT)10
2831 ,(USHORT)SPBQ_UPDATEIFVALID
2832 )
2833 );
2834 lVal = atol(zVal);
2835 bProcessed = OS2OnScroll( wxVERTICAL
2836 ,(WXWORD)SHORT2FROMMP(wParam)
2837 ,(WXWORD)lVal
2838 ,HWNDFROMMP(lParam)
2839 );
2840 }
2841 break;
2842
2843 case SLN_SLIDERTRACK:
2844 {
2845 HWND hWnd = ::WinWindowFromID(GetHWND(), SHORT1FROMMP(wParam));
2846 wxWindowOS2* pChild = wxFindWinFromHandle(hWnd);
2847
2848 if (!pChild)
2849 {
2850 bProcessed = false;
2851 break;
2852 }
2853 if (pChild->IsKindOf(CLASSINFO(wxSlider)))
2854 bProcessed = OS2OnScroll( wxVERTICAL
2855 ,(WXWORD)SHORT2FROMMP(wParam)
2856 ,(WXWORD)LONGFROMMP(lParam)
2857 ,hWnd
2858 );
2859 }
2860 break;
2861 }
2862 break;
2863
2864 #if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2865 case WM_CTLCOLORCHANGE:
2866 {
2867 bProcessed = HandleCtlColor(&hBrush);
2868 }
2869 break;
2870 #endif
2871 case WM_ERASEBACKGROUND:
2872 //
2873 // Returning TRUE to requestw PM to paint the window background
2874 // in SYSCLR_WINDOW. We don't really want that
2875 //
2876 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2877 mResult = (MRESULT)(FALSE);
2878 break;
2879
2880 // the return value for this message is ignored
2881 case WM_SYSCOLORCHANGE:
2882 bProcessed = HandleSysColorChange();
2883 break;
2884
2885 case WM_REALIZEPALETTE:
2886 bProcessed = HandlePaletteChanged();
2887 break;
2888
2889 // move all drag and drops to wxDrg
2890 case WM_ENDDRAG:
2891 bProcessed = HandleEndDrag(wParam);
2892 break;
2893
2894 case WM_INITDLG:
2895 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
2896
2897 if ( bProcessed )
2898 {
2899 // we never set focus from here
2900 mResult = (MRESULT)FALSE;
2901 }
2902 break;
2903
2904 // wxFrame specific message
2905 case WM_MINMAXFRAME:
2906 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
2907 break;
2908
2909 case WM_SYSVALUECHANGED:
2910 // TODO: do something
2911 mResult = (MRESULT)TRUE;
2912 break;
2913
2914 //
2915 // Comparable to WM_SETPOINTER for windows, only for just controls
2916 //
2917 case WM_CONTROLPOINTER:
2918 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2919 ,(HWND)lParam // Cursor Handle
2920 );
2921 if (bProcessed )
2922 {
2923 //
2924 // Returning TRUE stops the DefWindowProc() from further
2925 // processing this message - exactly what we need because we've
2926 // just set the cursor.
2927 //
2928 mResult = (MRESULT)TRUE;
2929 }
2930 break;
2931
2932 #if wxUSE_MENUS_NATIVE
2933 case WM_MENUEND:
2934 if (wxCurrentPopupMenu)
2935 {
2936 if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
2937 {
2938 // Break out of msg loop in DoPopupMenu
2939 ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
2940 }
2941 }
2942 break;
2943 #endif // wxUSE_MENUS_NATIVE
2944
2945 }
2946 if (!bProcessed)
2947 {
2948 #ifdef __WXDEBUG__
2949 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
2950 wxGetMessageName(uMsg));
2951 #endif // __WXDEBUG__
2952 if (IsKindOf(CLASSINFO(wxFrame)))
2953 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
2954 else if (IsKindOf(CLASSINFO(wxDialog)))
2955 mResult = ::WinDefDlgProc( m_hWnd, uMsg, wParam, lParam);
2956 else
2957 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
2958 }
2959 return mResult;
2960 } // end of wxWindowOS2::OS2WindowProc
2961
2962 // ----------------------------------------------------------------------------
2963 // wxWindow <-> HWND map
2964 // ----------------------------------------------------------------------------
2965
2966 wxWinHashTable *wxWinHandleHash = NULL;
2967
2968 wxWindow* wxFindWinFromHandle(
2969 WXHWND hWnd
2970 )
2971 {
2972 return (wxWindow *)wxWinHandleHash->Get((long)hWnd);
2973 } // end of wxFindWinFromHandle
2974
2975 void wxAssociateWinWithHandle(
2976 HWND hWnd
2977 , wxWindowOS2* pWin
2978 )
2979 {
2980 //
2981 // Adding NULL hWnd is (first) surely a result of an error and
2982 // (secondly) breaks menu command processing
2983 //
2984 wxCHECK_RET( hWnd != (HWND)NULL,
2985 wxT("attempt to add a NULL hWnd to window list ignored") );
2986
2987
2988 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
2989
2990 if (pOldWin && (pOldWin != pWin))
2991 {
2992 wxString str(pWin->GetClassInfo()->GetClassName());
2993
2994 wxLogError( _T("Bug! Found existing HWND %X for new window of class %s")
2995 ,(int)hWnd
2996 ,str.c_str()
2997 );
2998 }
2999 else if (!pOldWin)
3000 {
3001 wxWinHandleHash->Put( (long)hWnd
3002 ,(wxWindow *)pWin
3003 );
3004 }
3005 } // end of wxAssociateWinWithHandle
3006
3007 void wxRemoveHandleAssociation( wxWindowOS2* pWin )
3008 {
3009 wxWinHandleHash->Delete((long)pWin->GetHWND());
3010 } // end of wxRemoveHandleAssociation
3011
3012 //
3013 // Default destroyer - override if you destroy it in some other way
3014 // (e.g. with MDI child windows)
3015 //
3016 void wxWindowOS2::OS2DestroyWindow()
3017 {
3018 }
3019
3020 bool wxWindowOS2::OS2GetCreateWindowCoords( const wxPoint& rPos,
3021 const wxSize& rSize,
3022 int& rnX,
3023 int& rnY,
3024 int& rnWidth,
3025 int& rnHeight ) const
3026 {
3027 bool bNonDefault = false;
3028 static const int DEFAULT_Y = 200;
3029 static const int DEFAULT_H = 250;
3030
3031 if (rPos.x == wxDefaultCoord)
3032 {
3033 rnX = rnY = CW_USEDEFAULT;
3034 }
3035 else
3036 {
3037 rnX = rPos.x;
3038 rnY = rPos.y == wxDefaultCoord ? DEFAULT_Y : rPos.y;
3039 bNonDefault = true;
3040 }
3041 if (rSize.x == wxDefaultCoord)
3042 {
3043 rnWidth = rnHeight = CW_USEDEFAULT;
3044 }
3045 else
3046 {
3047 rnWidth = rSize.x;
3048 rnHeight = rSize.y == wxDefaultCoord ? DEFAULT_H : rSize.y;
3049 bNonDefault = true;
3050 }
3051 return bNonDefault;
3052 } // end of wxWindowOS2::OS2GetCreateWindowCoords
3053
3054 WXHWND wxWindowOS2::OS2GetParent() const
3055 {
3056 return m_parent ? m_parent->GetHWND() : NULL;
3057 }
3058
3059 bool wxWindowOS2::OS2Create( PSZ zClass,
3060 const wxChar* zTitle,
3061 WXDWORD dwStyle,
3062 const wxPoint& rPos,
3063 const wxSize& rSize,
3064 void* pCtlData,
3065 WXDWORD WXUNUSED(dwExStyle),
3066 bool bIsChild )
3067 {
3068 ERRORID vError;
3069 wxString sError;
3070 int nX = 0L;
3071 int nY = 0L;
3072 int nWidth = 0L;
3073 int nHeight = 0L;
3074 long lControlId = 0L;
3075 wxWindowCreationHook vHook(this);
3076 wxString sClassName((wxChar*)zClass);
3077
3078 OS2GetCreateWindowCoords( rPos
3079 ,rSize
3080 ,nX
3081 ,nY
3082 ,nWidth
3083 ,nHeight
3084 );
3085
3086 if (bIsChild)
3087 {
3088 lControlId = GetId();
3089 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
3090 {
3091 dwStyle |= WS_CLIPSIBLINGS;
3092 }
3093 }
3094 //
3095 // For each class "Foo" we have we also have "FooNR" ("no repaint") class
3096 // which is the same but without CS_[HV]REDRAW class styles so using it
3097 // ensures that the window is not fully repainted on each resize
3098 //
3099 if (!HasFlag(wxFULL_REPAINT_ON_RESIZE))
3100 {
3101 sClassName += wxT("NR");
3102 }
3103 m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
3104 ,(PSZ)sClassName.c_str()
3105 ,(PSZ)(zTitle ? zTitle : wxEmptyString)
3106 ,(ULONG)dwStyle
3107 ,(LONG)0L
3108 ,(LONG)0L
3109 ,(LONG)0L
3110 ,(LONG)0L
3111 ,NULLHANDLE
3112 ,HWND_TOP
3113 ,(ULONG)lControlId
3114 ,pCtlData
3115 ,NULL
3116 );
3117 if (!m_hWnd)
3118 {
3119 vError = ::WinGetLastError(wxGetInstance());
3120 sError = wxPMErrorToStr(vError);
3121 return false;
3122 }
3123 SubclassWin(m_hWnd);
3124 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
3125
3126 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
3127
3128 LONG lColor = (LONG)m_backgroundColour.GetPixel();
3129
3130 if (!::WinSetPresParam( m_hWnd
3131 ,PP_BACKGROUNDCOLOR
3132 ,sizeof(LONG)
3133 ,(PVOID)&lColor
3134 ))
3135 {
3136 vError = ::WinGetLastError(vHabmain);
3137 sError = wxPMErrorToStr(vError);
3138 wxLogError(_T("Error creating frame. Error: %s\n"), sError.c_str());
3139 return false;
3140 }
3141 SetSize( nX
3142 ,nY
3143 ,nWidth
3144 ,nHeight
3145 );
3146 return true;
3147 } // end of WinGuiBase_Window::OS2Create
3148
3149 // ===========================================================================
3150 // OS2 PM message handlers
3151 // ===========================================================================
3152
3153 // ---------------------------------------------------------------------------
3154 // window creation/destruction
3155 // ---------------------------------------------------------------------------
3156
3157 bool wxWindowOS2::HandleCreate( WXLPCREATESTRUCT WXUNUSED(vCs),
3158 bool* pbMayCreate )
3159 {
3160 wxWindowCreateEvent vEvent((wxWindow*)this);
3161
3162 (void)GetEventHandler()->ProcessEvent(vEvent);
3163 *pbMayCreate = true;
3164 return true;
3165 } // end of wxWindowOS2::HandleCreate
3166
3167 bool wxWindowOS2::HandleDestroy()
3168 {
3169 wxWindowDestroyEvent vEvent((wxWindow*)this);
3170 vEvent.SetId(GetId());
3171 (void)GetEventHandler()->ProcessEvent(vEvent);
3172
3173 //
3174 // Delete our drop target if we've got one
3175 //
3176 #if wxUSE_DRAG_AND_DROP
3177 if (m_dropTarget != NULL)
3178 {
3179 delete m_dropTarget;
3180 m_dropTarget = NULL;
3181 }
3182 #endif // wxUSE_DRAG_AND_DROP
3183
3184 //
3185 // WM_DESTROY handled
3186 //
3187 return true;
3188 } // end of wxWindowOS2::HandleDestroy
3189
3190 // ---------------------------------------------------------------------------
3191 // activation/focus
3192 // ---------------------------------------------------------------------------
3193 void wxWindowOS2::OnSetFocus(
3194 wxFocusEvent& rEvent
3195 )
3196 {
3197 rEvent.Skip();
3198 } // end of wxWindowOS2::OnSetFocus
3199
3200 bool wxWindowOS2::HandleActivate(
3201 int nState
3202 , WXHWND WXUNUSED(hActivate)
3203 )
3204 {
3205 wxActivateEvent vEvent( wxEVT_ACTIVATE
3206 ,(bool)nState
3207 ,m_windowId
3208 );
3209 vEvent.SetEventObject(this);
3210 return GetEventHandler()->ProcessEvent(vEvent);
3211 } // end of wxWindowOS2::HandleActivate
3212
3213 bool wxWindowOS2::HandleSetFocus( WXHWND WXUNUSED(hWnd) )
3214 {
3215 //
3216 // Notify the parent keeping track of focus for the kbd navigation
3217 // purposes that we got it
3218 //
3219 wxChildFocusEvent vEventFocus((wxWindow *)this);
3220 (void)GetEventHandler()->ProcessEvent(vEventFocus);
3221
3222 #if wxUSE_CARET
3223 //
3224 // Deal with caret
3225 //
3226 if (m_caret)
3227 {
3228 m_caret->OnSetFocus();
3229 }
3230 #endif // wxUSE_CARET
3231
3232 #if wxUSE_TEXTCTRL
3233 // If it's a wxTextCtrl don't send the event as it will be done
3234 // after the control gets to process it from EN_FOCUS handler
3235 if ( wxDynamicCastThis(wxTextCtrl) )
3236 {
3237 return false;
3238 }
3239 #endif // wxUSE_TEXTCTRL
3240
3241 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
3242
3243 vEvent.SetEventObject(this);
3244 return GetEventHandler()->ProcessEvent(vEvent);
3245 } // end of wxWindowOS2::HandleSetFocus
3246
3247 bool wxWindowOS2::HandleKillFocus( WXHWND hWnd )
3248 {
3249 #if wxUSE_CARET
3250 //
3251 // Deal with caret
3252 //
3253 if (m_caret)
3254 {
3255 m_caret->OnKillFocus();
3256 }
3257 #endif // wxUSE_CARET
3258
3259 #if wxUSE_TEXTCTRL
3260 //
3261 // If it's a wxTextCtrl don't send the event as it will be done
3262 // after the control gets to process it.
3263 //
3264 wxTextCtrl* pCtrl = wxDynamicCastThis(wxTextCtrl);
3265
3266 if (pCtrl)
3267 {
3268 return false;
3269 }
3270 #endif
3271
3272 //
3273 // Don't send the event when in the process of being deleted. This can
3274 // only cause problems if the event handler tries to access the object.
3275 //
3276 if ( m_isBeingDeleted )
3277 {
3278 return false;
3279 }
3280
3281 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
3282 ,m_windowId
3283 );
3284
3285 vEvent.SetEventObject(this);
3286
3287 //
3288 // wxFindWinFromHandle() may return NULL, it is ok
3289 //
3290 vEvent.SetWindow(wxFindWinFromHandle(hWnd));
3291 return GetEventHandler()->ProcessEvent(vEvent);
3292 } // end of wxWindowOS2::HandleKillFocus
3293
3294 // ---------------------------------------------------------------------------
3295 // miscellaneous
3296 // ---------------------------------------------------------------------------
3297
3298 bool wxWindowOS2::HandleShow(
3299 bool bShow
3300 , int WXUNUSED(nStatus)
3301 )
3302 {
3303 wxShowEvent vEvent(GetId(), bShow);
3304
3305 vEvent.SetEventObject(this);
3306 return GetEventHandler()->ProcessEvent(vEvent);
3307 } // end of wxWindowOS2::HandleShow
3308
3309 bool wxWindowOS2::HandleInitDialog( WXHWND WXUNUSED(hWndFocus) )
3310 {
3311 wxInitDialogEvent vEvent(GetId());
3312
3313 vEvent.SetEventObject(this);
3314 return GetEventHandler()->ProcessEvent(vEvent);
3315 } // end of wxWindowOS2::HandleInitDialog
3316
3317 bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
3318 {
3319 // TODO: We'll handle drag and drop later
3320 return false;
3321 }
3322
3323 bool wxWindowOS2::HandleSetCursor( USHORT WXUNUSED(vId),
3324 WXHWND hPointer )
3325 {
3326 //
3327 // Under OS/2 PM this allows the pointer to be changed
3328 // as it passes over a control
3329 //
3330 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
3331 return true;
3332 } // end of wxWindowOS2::HandleSetCursor
3333
3334 // ---------------------------------------------------------------------------
3335 // owner drawn stuff
3336 // ---------------------------------------------------------------------------
3337 bool wxWindowOS2::OS2OnDrawItem( int vId,
3338 WXDRAWITEMSTRUCT* pItemStruct )
3339 {
3340 #if wxUSE_OWNER_DRAWN
3341 wxDC vDc;
3342
3343 #if wxUSE_MENUS_NATIVE
3344 //
3345 // Is it a menu item?
3346 //
3347 if (vId == 0)
3348 {
3349 ERRORID vError;
3350 wxString sError;
3351 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
3352 wxFrame* pFrame = (wxFrame*)this;
3353 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
3354 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
3355 wxRect vRect( pMeasureStruct->rclItem.xLeft
3356 ,pMeasureStruct->rclItem.yBottom
3357 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3358 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3359 );
3360 vDc.SetHDC( hDC, false );
3361 vDc.SetHPS( pMeasureStruct->hps );
3362 //
3363 // Load the wxWidgets Pallete and set to RGB mode
3364 //
3365 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3366 ,0L
3367 ,LCOLF_CONSECRGB
3368 ,0L
3369 ,(LONG)wxTheColourDatabase->m_nSize
3370 ,(PLONG)wxTheColourDatabase->m_palTable
3371 ))
3372 {
3373 vError = ::WinGetLastError(vHabmain);
3374 sError = wxPMErrorToStr(vError);
3375 wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
3376 }
3377 //
3378 // Set the color table to RGB mode
3379 //
3380 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3381 ,0L
3382 ,LCOLF_RGB
3383 ,0L
3384 ,0L
3385 ,NULL
3386 ))
3387 {
3388 vError = ::WinGetLastError(vHabmain);
3389 sError = wxPMErrorToStr(vError);
3390 wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
3391 }
3392
3393 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3394
3395 int eAction = 0;
3396 int eStatus = 0;
3397
3398 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
3399 {
3400 //
3401 // Entire Item needs to be redrawn (either it has reappeared from
3402 // behind another window or is being displayed for the first time
3403 //
3404 eAction = wxOwnerDrawn::wxODDrawAll;
3405
3406 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3407 {
3408 //
3409 // If it is currently selected we let the system handle it
3410 //
3411 eStatus |= wxOwnerDrawn::wxODSelected;
3412 }
3413 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3414 {
3415 //
3416 // If it is currently checked we draw our own
3417 //
3418 eStatus |= wxOwnerDrawn::wxODChecked;
3419 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3420 }
3421 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3422 {
3423 //
3424 // If it is currently disabled we let the system handle it
3425 //
3426 eStatus |= wxOwnerDrawn::wxODDisabled;
3427 }
3428 //
3429 // Don't really care about framed (indicationg focus) or NoDismiss
3430 //
3431 }
3432 else
3433 {
3434 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3435 {
3436 eAction = wxOwnerDrawn::wxODDrawAll;
3437 eStatus |= wxOwnerDrawn::wxODSelected;
3438 //
3439 // Keep the system from trying to highlight with its bogus colors
3440 //
3441 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3442 }
3443 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3444 {
3445 eAction = wxOwnerDrawn::wxODDrawAll;
3446 eStatus = 0;
3447 //
3448 // Keep the system from trying to highlight with its bogus colors
3449 //
3450 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3451 }
3452 else
3453 {
3454 //
3455 // For now we don't care about anything else
3456 // just ignore the entire message!
3457 //
3458 return true;
3459 }
3460 }
3461 //
3462 // Now redraw the item
3463 //
3464 return(pMenuItem->OnDrawItem( vDc
3465 ,vRect
3466 ,(wxOwnerDrawn::wxODAction)eAction
3467 ,(wxOwnerDrawn::wxODStatus)eStatus
3468 ));
3469 //
3470 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3471 // the system will do the highlight or fraeming or disabling for us,
3472 // otherwise, we'd have to do it ourselves.
3473 //
3474 }
3475 #endif // wxUSE_MENUS_NATIVE
3476
3477 wxWindow* pItem = FindItem(vId);
3478
3479 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3480 {
3481 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3482 }
3483 #else
3484 vId = vId;
3485 pItemStruct = pItemStruct;
3486 #endif
3487 return false;
3488 } // end of wxWindowOS2::OS2OnDrawItem
3489
3490 long wxWindowOS2::OS2OnMeasureItem( int lId,
3491 WXMEASUREITEMSTRUCT* pItemStruct )
3492 {
3493 #if wxUSE_OWNER_DRAWN
3494 //
3495 // Is it a menu item?
3496 //
3497 if (lId == 65536) // I really don't like this...has to be a better indicator
3498 {
3499 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
3500 {
3501 size_t nWidth;
3502 size_t nHeight;
3503 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
3504 wxFrame* pFrame = (wxFrame*)this;
3505 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
3506
3507 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3508 nWidth = 0L;
3509 nHeight = 0L;
3510 if (pMenuItem->OnMeasureItem( &nWidth
3511 ,&nHeight
3512 ))
3513 {
3514 MRESULT mRc;
3515
3516 pMeasureStruct->rclItem.xRight = nWidth;
3517 pMeasureStruct->rclItem.xLeft = 0L;
3518 pMeasureStruct->rclItem.yTop = nHeight;
3519 pMeasureStruct->rclItem.yBottom = 0L;
3520 mRc = MRFROM2SHORT(nHeight, nWidth);
3521 return LONGFROMMR(mRc);
3522 }
3523 return 0L;
3524 }
3525 }
3526 wxWindow* pItem = FindItem(lId);
3527
3528 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3529 {
3530 OWNERITEM vItem;
3531
3532 vItem.idItem = (LONG)pItemStruct;
3533 return ((wxControl *)pItem)->OS2OnMeasure((WXMEASUREITEMSTRUCT*)&vItem);
3534 }
3535 #else
3536 lId = lId;
3537 pItemStruct = pItemStruct;
3538 #endif // wxUSE_OWNER_DRAWN
3539 return FALSE;
3540 }
3541
3542 // ---------------------------------------------------------------------------
3543 // colours and palettes
3544 // ---------------------------------------------------------------------------
3545
3546 bool wxWindowOS2::HandleSysColorChange()
3547 {
3548 wxSysColourChangedEvent vEvent;
3549
3550 vEvent.SetEventObject(this);
3551 return GetEventHandler()->ProcessEvent(vEvent);
3552 } // end of wxWindowOS2::HandleSysColorChange
3553
3554 bool wxWindowOS2::HandleCtlColor( WXHBRUSH* WXUNUSED(phBrush) )
3555 {
3556 //
3557 // Not much provided with message. So not sure I can do anything with it
3558 //
3559 return true;
3560 } // end of wxWindowOS2::HandleCtlColor
3561
3562
3563 // Define for each class of dialog and control
3564 WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
3565 WXHWND WXUNUSED(hWnd),
3566 WXUINT WXUNUSED(nCtlColor),
3567 WXUINT WXUNUSED(message),
3568 WXWPARAM WXUNUSED(wParam),
3569 WXLPARAM WXUNUSED(lParam))
3570 {
3571 return (WXHBRUSH)0;
3572 }
3573
3574 bool wxWindowOS2::HandlePaletteChanged()
3575 {
3576 // need to set this to something first
3577 WXHWND hWndPalChange = NULLHANDLE;
3578
3579 wxPaletteChangedEvent vEvent(GetId());
3580
3581 vEvent.SetEventObject(this);
3582 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
3583
3584 return GetEventHandler()->ProcessEvent(vEvent);
3585 } // end of wxWindowOS2::HandlePaletteChanged
3586
3587 //
3588 // Responds to colour changes: passes event on to children.
3589 //
3590 void wxWindowOS2::OnSysColourChanged(
3591 wxSysColourChangedEvent& rEvent
3592 )
3593 {
3594 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
3595
3596 while (node)
3597 {
3598 //
3599 // Only propagate to non-top-level windows
3600 //
3601 wxWindow* pWin = (wxWindow *)node->GetData();
3602
3603 if (pWin->GetParent())
3604 {
3605 wxSysColourChangedEvent vEvent;
3606
3607 rEvent.SetEventObject(pWin);
3608 pWin->GetEventHandler()->ProcessEvent(vEvent);
3609 }
3610 node = node->GetNext();
3611 }
3612 } // end of wxWindowOS2::OnSysColourChanged
3613
3614 // ---------------------------------------------------------------------------
3615 // painting
3616 // ---------------------------------------------------------------------------
3617
3618 void wxWindow::OnPaint (
3619 wxPaintEvent& rEvent
3620 )
3621 {
3622 HDC hDC = (HDC)wxPaintDC::FindDCInCache((wxWindow*) rEvent.GetEventObject());
3623
3624 if (hDC != 0)
3625 {
3626 OS2DefWindowProc( (WXUINT)WM_PAINT
3627 ,(WXWPARAM)hDC
3628 ,(WXLPARAM)0
3629 );
3630 }
3631 } // end of wxWindow::OnPaint
3632
3633 bool wxWindowOS2::HandlePaint()
3634 {
3635 HRGN hRgn;
3636 wxPaintEvent vEvent(m_windowId);
3637 HPS hPS;
3638 bool bProcessed;
3639
3640 // Create empty region
3641 // TODO: get HPS somewhere else if possible
3642 hPS = ::WinGetPS(GetHwnd());
3643 hRgn = ::GpiCreateRegion(hPS, 0, NULL);
3644
3645 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
3646 {
3647 wxLogLastError(wxT("CreateRectRgn"));
3648 return false;
3649 }
3650
3651 // Get all the rectangles from the region, convert the individual
3652 // rectangles to "the other" coordinate system and reassemble a
3653 // region from the rectangles, to be feed into m_updateRegion.
3654 //
3655 // FIXME: This is a bad hack since OS/2 API specifies that rectangles
3656 // passed into GpiSetRegion must not have Bottom > Top,
3657 // however, at first sight, it _seems_ to work nonetheless.
3658 //
3659 RGNRECT vRgnData;
3660 PRECTL pUpdateRects = NULL;
3661 vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
3662 if (::GpiQueryRegionRects( hPS // Pres space
3663 ,hRgn // Handle of region to query
3664 ,NULL // Return all RECTs
3665 ,&vRgnData // Will contain number or RECTs in region
3666 ,NULL // NULL to return number of RECTs
3667 ))
3668 {
3669 pUpdateRects = new RECTL[vRgnData.crcReturned];
3670 vRgnData.crc = vRgnData.crcReturned;
3671 vRgnData.ircStart = 1;
3672 if (::GpiQueryRegionRects( hPS // Pres space of source
3673 ,hRgn // Handle of source region
3674 ,NULL // Return all RECTs
3675 ,&vRgnData // Operations set to return rects
3676 ,pUpdateRects // Will contain the actual RECTS
3677 ))
3678 {
3679 int height;
3680 RECT vRect;
3681 ::WinQueryWindowRect(GetHwnd(), &vRect);
3682 height = vRect.yTop;
3683
3684 for(size_t i = 0; i < vRgnData.crc; i++)
3685 {
3686 int rectHeight;
3687 rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
3688 pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
3689 pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
3690 }
3691 ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
3692 delete [] pUpdateRects;
3693 }
3694 }
3695
3696 m_updateRegion = wxRegion(hRgn, hPS);
3697
3698 vEvent.SetEventObject(this);
3699 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
3700
3701 if (!bProcessed &&
3702 IsKindOf(CLASSINFO(wxPanel)) &&
3703 GetChildren().GetCount() == 0
3704 )
3705 {
3706 //
3707 // OS/2 needs to process this right here, not by the default proc
3708 // Window's default proc correctly paints everything, OS/2 does not.
3709 // For decorative panels that typically have no children, we draw
3710 // borders.
3711 //
3712 HPS hPS;
3713 RECTL vRect;
3714
3715 hPS = ::WinBeginPaint( GetHwnd()
3716 ,NULLHANDLE
3717 ,&vRect
3718 );
3719 if(hPS)
3720 {
3721 ::GpiCreateLogColorTable( hPS
3722 ,0L
3723 ,LCOLF_CONSECRGB
3724 ,0L
3725 ,(LONG)wxTheColourDatabase->m_nSize
3726 ,(PLONG)wxTheColourDatabase->m_palTable
3727 );
3728 ::GpiCreateLogColorTable( hPS
3729 ,0L
3730 ,LCOLF_RGB
3731 ,0L
3732 ,0L
3733 ,NULL
3734 );
3735 if (::WinIsWindowVisible(GetHWND()))
3736 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3737 if (m_dwExStyle)
3738 {
3739 LINEBUNDLE vLineBundle;
3740
3741 vLineBundle.lColor = 0x00000000; // Black
3742 vLineBundle.usMixMode = FM_OVERPAINT;
3743 vLineBundle.fxWidth = 1;
3744 vLineBundle.lGeomWidth = 1;
3745 vLineBundle.usType = LINETYPE_SOLID;
3746 vLineBundle.usEnd = 0;
3747 vLineBundle.usJoin = 0;
3748 ::GpiSetAttrs( hPS
3749 ,PRIM_LINE
3750 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
3751 ,0L
3752 ,&vLineBundle
3753 );
3754 ::WinQueryWindowRect(GetHwnd(), &vRect);
3755 wxDrawBorder( hPS
3756 ,vRect
3757 ,m_dwExStyle
3758 );
3759 }
3760 }
3761 ::WinEndPaint(hPS);
3762 bProcessed = true;
3763 }
3764 else if (!bProcessed &&
3765 IsKindOf(CLASSINFO(wxPanel))
3766 )
3767 {
3768 //
3769 // Panel with children, usually fills a frame client so no borders.
3770 //
3771 HPS hPS;
3772 RECTL vRect;
3773
3774 hPS = ::WinBeginPaint( GetHwnd()
3775 ,NULLHANDLE
3776 ,&vRect
3777 );
3778 if(hPS)
3779 {
3780 ::GpiCreateLogColorTable( hPS
3781 ,0L
3782 ,LCOLF_CONSECRGB
3783 ,0L
3784 ,(LONG)wxTheColourDatabase->m_nSize
3785 ,(PLONG)wxTheColourDatabase->m_palTable
3786 );
3787 ::GpiCreateLogColorTable( hPS
3788 ,0L
3789 ,LCOLF_RGB
3790 ,0L
3791 ,0L
3792 ,NULL
3793 );
3794
3795 if (::WinIsWindowVisible(GetHWND()))
3796 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3797 }
3798 ::WinEndPaint(hPS);
3799 bProcessed = true;
3800 }
3801 return bProcessed;
3802 } // end of wxWindowOS2::HandlePaint
3803
3804 bool wxWindowOS2::HandleEraseBkgnd( WXHDC hDC )
3805 {
3806 SWP vSwp;
3807 bool rc;
3808
3809 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3810 if (vSwp.fl & SWP_MINIMIZE)
3811 return true;
3812
3813 wxDC vDC;
3814
3815 vDC.m_hPS = (HPS)hDC; // this is really a PS
3816 vDC.SetWindow((wxWindow*)this);
3817 vDC.BeginDrawing();
3818
3819 wxEraseEvent vEvent(m_windowId, &vDC);
3820
3821 vEvent.SetEventObject(this);
3822
3823 rc = GetEventHandler()->ProcessEvent(vEvent);
3824
3825 vDC.EndDrawing();
3826 vDC.m_hPS = NULLHANDLE;
3827 return true;
3828 } // end of wxWindowOS2::HandleEraseBkgnd
3829
3830 void wxWindowOS2::OnEraseBackground(wxEraseEvent& rEvent)
3831 {
3832 RECTL vRect;
3833 HPS hPS = rEvent.GetDC()->GetHPS();
3834 APIRET rc;
3835 LONG lColor = m_backgroundColour.GetPixel();
3836
3837 rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
3838 rc = ::WinFillRect(hPS, &vRect, lColor);
3839 } // end of wxWindowOS2::OnEraseBackground
3840
3841 // ---------------------------------------------------------------------------
3842 // moving and resizing
3843 // ---------------------------------------------------------------------------
3844
3845 bool wxWindowOS2::HandleMinimize()
3846 {
3847 wxIconizeEvent vEvent(m_windowId);
3848
3849 vEvent.SetEventObject(this);
3850 return GetEventHandler()->ProcessEvent(vEvent);
3851 } // end of wxWindowOS2::HandleMinimize
3852
3853 bool wxWindowOS2::HandleMaximize()
3854 {
3855 wxMaximizeEvent vEvent(m_windowId);
3856
3857 vEvent.SetEventObject(this);
3858 return GetEventHandler()->ProcessEvent(vEvent);
3859 } // end of wxWindowOS2::HandleMaximize
3860
3861 bool wxWindowOS2::HandleMove( int nX, int nY )
3862 {
3863 wxPoint pt(nX, nY);
3864 wxMoveEvent vEvent(pt, m_windowId);
3865
3866 vEvent.SetEventObject(this);
3867 return GetEventHandler()->ProcessEvent(vEvent);
3868 } // end of wxWindowOS2::HandleMove
3869
3870 bool wxWindowOS2::HandleSize( int nWidth,
3871 int nHeight,
3872 WXUINT WXUNUSED(nFlag) )
3873 {
3874 wxSize sz(nWidth, nHeight);
3875 wxSizeEvent vEvent(sz, m_windowId);
3876
3877 vEvent.SetEventObject(this);
3878 return GetEventHandler()->ProcessEvent(vEvent);
3879 } // end of wxWindowOS2::HandleSize
3880
3881 bool wxWindowOS2::HandleGetMinMaxInfo( PSWP pSwp )
3882 {
3883 POINTL vPoint;
3884
3885 switch(pSwp->fl)
3886 {
3887 case SWP_MAXIMIZE:
3888 ::WinGetMaxPosition(GetHwnd(), pSwp);
3889 m_maxWidth = pSwp->cx;
3890 m_maxHeight = pSwp->cy;
3891 break;
3892
3893 case SWP_MINIMIZE:
3894 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3895 m_minWidth = pSwp->cx;
3896 m_minHeight = pSwp->cy;
3897 break;
3898
3899 default:
3900 return false;
3901 }
3902 return true;
3903 } // end of wxWindowOS2::HandleGetMinMaxInfo
3904
3905 // ---------------------------------------------------------------------------
3906 // command messages
3907 // ---------------------------------------------------------------------------
3908 bool wxWindowOS2::HandleCommand( WXWORD wId,
3909 WXWORD wCmd,
3910 WXHWND hControl )
3911 {
3912 #if wxUSE_MENUS_NATIVE
3913 if (wxCurrentPopupMenu)
3914 {
3915 wxMenu* pPopupMenu = wxCurrentPopupMenu;
3916
3917 wxCurrentPopupMenu = NULL;
3918 return pPopupMenu->OS2Command(wCmd, wId);
3919 }
3920 #endif // wxUSE_MENUS_NATIVE
3921
3922 wxWindow* pWin = FindItem(wId);
3923
3924 if (!pWin)
3925 {
3926 pWin = wxFindWinFromHandle(hControl);
3927 }
3928
3929 if (pWin)
3930 return pWin->OS2Command(wCmd, wId);
3931
3932 return false;
3933 } // end of wxWindowOS2::HandleCommand
3934
3935 bool wxWindowOS2::HandleSysCommand( WXWPARAM wParam,
3936 WXLPARAM WXUNUSED(lParam) )
3937 {
3938 //
3939 // 4 bits are reserved
3940 //
3941 switch (SHORT1FROMMP(wParam))
3942 {
3943 case SC_MAXIMIZE:
3944 return HandleMaximize();
3945
3946 case SC_MINIMIZE:
3947 return HandleMinimize();
3948 }
3949 return false;
3950 } // end of wxWindowOS2::HandleSysCommand
3951
3952 // ---------------------------------------------------------------------------
3953 // mouse events
3954 // ---------------------------------------------------------------------------
3955 //TODO: check against MSW
3956 void wxWindowOS2::InitMouseEvent(
3957 wxMouseEvent& rEvent
3958 , int nX
3959 , int nY
3960 , WXUINT uFlags
3961 )
3962 {
3963 int nHeight;
3964 DoGetSize(0, &nHeight);
3965 rEvent.m_x = nX;
3966 // Convert to wxWidgets standard coordinate system!
3967 rEvent.m_y = nHeight - nY;
3968 rEvent.m_shiftDown = ((uFlags & KC_SHIFT) != 0);
3969 rEvent.m_controlDown = ((uFlags & KC_CTRL) != 0);
3970 rEvent.m_altDown = ((uFlags & KC_ALT) != 0);
3971 rEvent.m_leftDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
3972 0x8000) != 0;
3973 rEvent.m_middleDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &
3974 0x8000) != 0;
3975 rEvent.m_rightDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
3976 0x8000) != 0;
3977 rEvent.SetTimestamp(s_currentMsg.time);
3978 rEvent.SetEventObject(this);
3979 rEvent.SetId(GetId());
3980
3981 #if wxUSE_MOUSEEVENT_HACK
3982 m_lastMouseX = nX;
3983 m_lastMouseY = nY;
3984 m_lastMouseEvent = rEvent.GetEventType();
3985 #endif // wxUSE_MOUSEEVENT_HACK
3986 } // end of wxWindowOS2::InitMouseEvent
3987
3988 bool wxWindowOS2::HandleMouseEvent( WXUINT uMsg,
3989 int nX,
3990 int nY,
3991 WXUINT uFlags )
3992 {
3993 bool bProcessed = false;
3994
3995 //
3996 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
3997 // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
3998 // from the message id and take the value in the table to get wxWin event
3999 // id
4000 //
4001 static const wxEventType eventsMouse[] =
4002 {
4003 wxEVT_MOTION,
4004 wxEVT_LEFT_DOWN,
4005 wxEVT_LEFT_UP,
4006 wxEVT_LEFT_DCLICK,
4007 wxEVT_RIGHT_DOWN,
4008 wxEVT_RIGHT_UP,
4009 wxEVT_RIGHT_DCLICK,
4010 wxEVT_MIDDLE_DOWN,
4011 wxEVT_MIDDLE_UP,
4012 wxEVT_MIDDLE_DCLICK
4013 };
4014
4015 // Bounds check
4016 if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
4017 {
4018 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
4019
4020 InitMouseEvent( vEvent
4021 ,nX
4022 ,nY
4023 ,uFlags
4024 );
4025
4026 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
4027 if (!bProcessed)
4028 {
4029 HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
4030
4031 if (hCursor != NULLHANDLE)
4032 {
4033 ::WinSetPointer(HWND_DESKTOP, hCursor);
4034 bProcessed = true;
4035 }
4036 }
4037 }
4038 return bProcessed;
4039 } // end of wxWindowOS2::HandleMouseEvent
4040
4041 bool wxWindowOS2::HandleMouseMove( int nX,
4042 int nY,
4043 WXUINT uFlags )
4044 {
4045 if (!m_bMouseInWindow)
4046 {
4047 //
4048 // Generate an ENTER event
4049 //
4050 m_bMouseInWindow = true;
4051
4052 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
4053
4054 InitMouseEvent( vEvent
4055 ,nX
4056 ,nY
4057 ,uFlags
4058 );
4059
4060 (void)GetEventHandler()->ProcessEvent(vEvent);
4061 }
4062 return HandleMouseEvent( WM_MOUSEMOVE
4063 ,nX
4064 ,nY
4065 ,uFlags
4066 );
4067 } // end of wxWindowOS2::HandleMouseMove
4068
4069 // ---------------------------------------------------------------------------
4070 // keyboard handling
4071 // ---------------------------------------------------------------------------
4072
4073 //
4074 // Create the key event of the given type for the given key - used by
4075 // HandleChar and HandleKeyDown/Up
4076 //
4077 wxKeyEvent wxWindowOS2::CreateKeyEvent(
4078 wxEventType eType
4079 , int nId
4080 , WXLPARAM lParam
4081 , WXWPARAM wParam
4082 ) const
4083 {
4084 wxKeyEvent vEvent(eType);
4085
4086 vEvent.SetId(GetId());
4087 vEvent.m_shiftDown = IsShiftDown();
4088 vEvent.m_controlDown = IsCtrlDown();
4089 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
4090
4091 vEvent.SetEventObject((wxWindow *)this); // const_cast
4092 vEvent.m_keyCode = nId;
4093 vEvent.m_rawCode = (wxUint32)wParam;
4094 vEvent.m_rawFlags = (wxUint32)lParam;
4095 vEvent.SetTimestamp(s_currentMsg.time);
4096
4097 //
4098 // Translate the position to client coords
4099 //
4100 POINTL vPoint;
4101 RECTL vRect;
4102
4103 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
4104 ::WinQueryWindowRect( GetHwnd()
4105 ,&vRect
4106 );
4107
4108 vPoint.x -= vRect.xLeft;
4109 vPoint.y -= vRect.yBottom;
4110
4111 vEvent.m_x = vPoint.x;
4112 vEvent.m_y = vPoint.y;
4113
4114 return vEvent;
4115 } // end of wxWindowOS2::CreateKeyEvent
4116
4117 //
4118 // isASCII is true only when we're called from WM_CHAR handler and not from
4119 // WM_KEYDOWN one
4120 //
4121 bool wxWindowOS2::HandleChar( WXWPARAM WXUNUSED(wParam),
4122 WXLPARAM lParam,
4123 bool isASCII )
4124 {
4125 bool bCtrlDown = false;
4126 int vId;
4127
4128 if (m_bLastKeydownProcessed)
4129 {
4130 //
4131 // The key was handled in the EVT_KEY_DOWN. Handling a key in an
4132 // EVT_KEY_DOWN handler is meant, by design, to prevent EVT_CHARs
4133 // from happening, so just bail out at this point.
4134 //
4135 m_bLastKeydownProcessed = false;
4136 return true;
4137 }
4138 if (isASCII)
4139 {
4140 //
4141 // If 1 -> 26, translate to either special keycode or just set
4142 // ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
4143 // ControlDown() == true.
4144 //
4145 vId = SHORT1FROMMP(lParam);
4146 if ((vId > 0) && (vId < 27))
4147 {
4148 switch (vId)
4149 {
4150 case 13:
4151 vId = WXK_RETURN;
4152 break;
4153
4154 case 8:
4155 vId = WXK_BACK;
4156 break;
4157
4158 case 9:
4159 vId = WXK_TAB;
4160 break;
4161
4162 default:
4163 bCtrlDown = true;
4164 break;
4165 }
4166 }
4167 }
4168 else // we're called from WM_KEYDOWN
4169 {
4170 vId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
4171 if (vId == 0)
4172 return false;
4173 }
4174
4175 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR, vId, lParam ));
4176
4177 if (bCtrlDown)
4178 {
4179 vEvent.m_controlDown = true;
4180 }
4181
4182 return (GetEventHandler()->ProcessEvent(vEvent));
4183 }
4184
4185 bool wxWindowOS2::HandleKeyDown( WXWPARAM wParam,
4186 WXLPARAM lParam )
4187 {
4188 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
4189
4190 if (!nId)
4191 {
4192 //
4193 // Normal ASCII char
4194 //
4195 nId = SHORT1FROMMP(lParam);
4196 }
4197
4198 if (nId != -1)
4199 {
4200 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
4201 ,nId
4202 ,(MPARAM)lParam
4203 ,(MPARAM)wParam
4204 ));
4205
4206 if (GetEventHandler()->ProcessEvent(vEvent))
4207 {
4208 return true;
4209 }
4210 }
4211 return false;
4212 } // end of wxWindowOS2::HandleKeyDown
4213
4214 bool wxWindowOS2::HandleKeyUp( WXWPARAM wParam,
4215 WXLPARAM lParam )
4216 {
4217 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
4218
4219 if (!nId)
4220 {
4221 //
4222 // Normal ASCII char
4223 //
4224 nId = CHAR1FROMMP(lParam);
4225 }
4226
4227 if (nId != -1)
4228 {
4229 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
4230 ,nId
4231 ,(MPARAM)lParam
4232 ,(MPARAM)wParam
4233 ));
4234
4235 if (GetEventHandler()->ProcessEvent(vEvent))
4236 return true;
4237 }
4238 return false;
4239 } // end of wxWindowOS2::HandleKeyUp
4240
4241 // ---------------------------------------------------------------------------
4242 // joystick
4243 // ---------------------------------------------------------------------------
4244
4245 // ---------------------------------------------------------------------------
4246 // scrolling
4247 // ---------------------------------------------------------------------------
4248
4249 bool wxWindowOS2::OS2OnScroll( int nOrientation,
4250 WXWORD wParam,
4251 WXWORD wPos,
4252 WXHWND hControl )
4253 {
4254 if (hControl)
4255 {
4256 wxWindow* pChild = wxFindWinFromHandle(hControl);
4257
4258 if (pChild )
4259 return pChild->OS2OnScroll( nOrientation
4260 ,wParam
4261 ,wPos
4262 ,hControl
4263 );
4264 }
4265
4266 wxScrollWinEvent vEvent;
4267
4268 vEvent.SetPosition(wPos);
4269 vEvent.SetOrientation(nOrientation);
4270 vEvent.SetEventObject(this);
4271
4272 switch (wParam)
4273 {
4274 case SB_LINEUP:
4275 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEUP);
4276 break;
4277
4278 case SB_LINEDOWN:
4279 vEvent.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
4280 break;
4281
4282 case SB_PAGEUP:
4283 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
4284 break;
4285
4286 case SB_PAGEDOWN:
4287 vEvent.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
4288 break;
4289
4290 case SB_SLIDERPOSITION:
4291 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBRELEASE);
4292 break;
4293
4294 case SB_SLIDERTRACK:
4295 vEvent.SetEventType(wxEVT_SCROLLWIN_THUMBTRACK);
4296 break;
4297
4298 default:
4299 return false;
4300 }
4301 return GetEventHandler()->ProcessEvent(vEvent);
4302 } // end of wxWindowOS2::OS2OnScroll
4303
4304 void wxWindowOS2::MoveChildren(
4305 int nDiff
4306 )
4307 {
4308 //
4309 // We want to handle top levels ourself, manually
4310 //
4311 if (!IsTopLevel() && GetAutoLayout())
4312 {
4313 Layout();
4314 }
4315 else
4316 {
4317 SWP vSwp;
4318
4319 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
4320 node;
4321 node = node->GetNext())
4322 {
4323 wxWindow* pWin = node->GetData();
4324
4325 ::WinQueryWindowPos( GetHwndOf(pWin)
4326 ,&vSwp
4327 );
4328 // Actually, only move children that already are placed on the
4329 // frame, not ones which are still at wxDefaultCoord.
4330 if (vSwp.y == wxDefaultCoord)
4331 continue;
4332 if (pWin->IsKindOf(CLASSINFO(wxControl)))
4333 {
4334 wxControl* pCtrl;
4335
4336 //
4337 // Must deal with controls that have margins like ENTRYFIELD. The SWP
4338 // struct of such a control will have and origin offset from its intended
4339 // position by the width of the margins.
4340 //
4341 pCtrl = wxDynamicCast(pWin, wxControl);
4342 vSwp.y -= pCtrl->GetYComp();
4343 vSwp.x -= pCtrl->GetXComp();
4344 }
4345 ::WinSetWindowPos( GetHwndOf(pWin)
4346 ,HWND_TOP
4347 ,vSwp.x
4348 ,vSwp.y - nDiff
4349 ,vSwp.cx
4350 ,vSwp.cy
4351 ,SWP_MOVE
4352 );
4353 ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
4354 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
4355 {
4356 wxRadioBox* pRadioBox;
4357
4358 pRadioBox = wxDynamicCast(pWin, wxRadioBox);
4359 pRadioBox->AdjustButtons( (int)vSwp.x
4360 ,(int)vSwp.y - nDiff
4361 ,(int)vSwp.cx
4362 ,(int)vSwp.cy
4363 ,pRadioBox->GetSizeFlags()
4364 );
4365 }
4366 if (pWin->IsKindOf(CLASSINFO(wxSlider)))
4367 {
4368 wxSlider* pSlider;
4369
4370 pSlider = wxDynamicCast(pWin, wxSlider);
4371 pSlider->AdjustSubControls( (int)vSwp.x
4372 ,(int)vSwp.y - nDiff
4373 ,(int)vSwp.cx
4374 ,(int)vSwp.cy
4375 ,(int)pSlider->GetSizeFlags()
4376 );
4377 }
4378 }
4379 }
4380 Refresh();
4381 } // end of wxWindowOS2::MoveChildren
4382
4383 //
4384 // Getting the Y position for a window, like a control, is a real
4385 // pain. There are three sitatuions we must deal with in determining
4386 // the OS2 to wxWidgets Y coordinate.
4387 //
4388 // 1) The controls are created in a dialog.
4389 // This is the easiest since a dialog is created with its original
4390 // size so the standard: Y = ParentHeight - (Y + ControlHeight);
4391 //
4392 // 2) The controls are direct children of a frame
4393 // In this instance the controls are actually children of the Frame's
4394 // client. During creation the frame's client resizes several times
4395 // during creation of the status bar and toolbars. The CFrame class
4396 // will take care of this using its AlterChildPos proc.
4397 //
4398 // 3) The controls are children of a panel, which in turn is a child of
4399 // a frame.
4400 // The panel may be one of many, in which case the same treatment
4401 // as 1 applies. It may be the only child, though.
4402 // This is the nastiest case. A panel is created as the only child of
4403 // the frame and as such, when a frame has only one child, the child is
4404 // expanded to fit the entire client area of the frame. Because the
4405 // controls are created BEFORE this occurs their positions are totally
4406 // whacked and any call to WinQueryWindowPos will return invalid
4407 // coordinates. So for this situation we have to compare the size of
4408 // the panel at control creation time with that of the frame client. If
4409 // they are the same we can use the standard Y position equation. If
4410 // not, then we must use the Frame Client's dimensions to position them
4411 // as that will be the eventual size of the panel after the frame resizes
4412 // it!
4413 //
4414 int wxWindowOS2::GetOS2ParentHeight( wxWindowOS2* pParent )
4415 {
4416 //
4417 // Case 1
4418 //
4419 if (pParent->IsKindOf(CLASSINFO(wxDialog)))
4420 return(pParent->GetClientSize().y);
4421
4422 //
4423 // Case 2 -- if we are one of the separately built standard Frame
4424 // children, like a statusbar, menubar, or toolbar we want to
4425 // use the frame, itself, for positioning. Otherwise we are
4426 // child window and want to use the Frame's client.
4427 //
4428 else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
4429 {
4430 if (IsKindOf(CLASSINFO(wxStatusBar)) ||
4431 IsKindOf(CLASSINFO(wxMenuBar)) ||
4432 IsKindOf(CLASSINFO(wxToolBar))
4433 )
4434 {
4435 if (IsKindOf(CLASSINFO(wxToolBar)))
4436 {
4437 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
4438
4439 if (pFrame->GetToolBar() == this)
4440 return(pParent->GetSize().y);
4441 else
4442 return(pParent->GetClientSize().y);
4443 }
4444 else
4445 return(pParent->GetSize().y);
4446 }
4447 else
4448 return(pParent->GetClientSize().y);
4449 }
4450 //
4451 // Case -- this is for any window that is the sole child of a Frame.
4452 // The grandparent must exist and it must be of type CFrame
4453 // and it's height must be different. Otherwise the standard
4454 // applies.
4455 //
4456 // else
4457 // {
4458
4459 return(pParent->GetClientSize().y);
4460
4461 // }
4462 } // end of wxWindowOS2::GetOS2ParentHeight
4463
4464 //
4465 // OS/2 needs a lot extra manipulation to deal with layouts
4466 // for canvas windows, particularly scrolled ones.
4467 //
4468 wxWindowCreationHook::wxWindowCreationHook(
4469 wxWindow* pWinBeingCreated
4470 )
4471 {
4472 gpWinBeingCreated = pWinBeingCreated;
4473 } // end of wxWindowCreationHook::wxWindowCreationHook
4474
4475 wxWindowCreationHook::~wxWindowCreationHook()
4476 {
4477 gpWinBeingCreated = NULL;
4478 } // end of wxWindowCreationHook::~wxWindowCreationHook
4479
4480 // ===========================================================================
4481 // global functions
4482 // ===========================================================================
4483
4484 void wxGetCharSize(
4485 WXHWND hWnd
4486 , int* pX
4487 , int* pY
4488 ,wxFont* WXUNUSED(pTheFont)
4489 )
4490 {
4491 FONTMETRICS vFM;
4492 HPS hPS;
4493 BOOL rc;
4494
4495 hPS =::WinGetPS(hWnd);
4496
4497 rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
4498 if (rc)
4499 {
4500 if (pX)
4501 *pX = vFM.lAveCharWidth;
4502 if (pY)
4503 *pY = vFM.lEmHeight + vFM.lExternalLeading;
4504 }
4505 else
4506 {
4507 if (pX)
4508 *pX = 10;
4509 if (pY)
4510 *pY = 15;
4511 }
4512 ::WinReleasePS(hPS);
4513 } // end of wxGetCharSize
4514
4515 //
4516 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
4517 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
4518 //
4519 int wxCharCodeOS2ToWX(
4520 int nKeySym
4521 )
4522 {
4523 int nId = 0;
4524
4525 switch (nKeySym)
4526 {
4527 case VK_BACKTAB: nId = WXK_BACK; break;
4528 case VK_TAB: nId = WXK_TAB; break;
4529 case VK_CLEAR: nId = WXK_CLEAR; break;
4530 case VK_ENTER: nId = WXK_RETURN; break;
4531 case VK_SHIFT: nId = WXK_SHIFT; break;
4532 case VK_CTRL: nId = WXK_CONTROL; break;
4533 case VK_PAUSE: nId = WXK_PAUSE; break;
4534 case VK_SPACE: nId = WXK_SPACE; break;
4535 case VK_PAGEUP: nId = WXK_PRIOR; break;
4536 case VK_PAGEDOWN: nId = WXK_NEXT; break;
4537 case VK_ESC: nId = WXK_ESCAPE; break;
4538 case VK_END: nId = WXK_END; break;
4539 case VK_HOME : nId = WXK_HOME; break;
4540 case VK_LEFT : nId = WXK_LEFT; break;
4541 case VK_UP: nId = WXK_UP; break;
4542 case VK_RIGHT: nId = WXK_RIGHT; break;
4543 case VK_DOWN : nId = WXK_DOWN; break;
4544 case VK_PRINTSCRN: nId = WXK_PRINT; break;
4545 case VK_INSERT: nId = WXK_INSERT; break;
4546 case VK_DELETE: nId = WXK_DELETE; break;
4547 case VK_CAPSLOCK: nId = WXK_CAPITAL; break;
4548 case VK_F1: nId = WXK_F1; break;
4549 case VK_F2: nId = WXK_F2; break;
4550 case VK_F3: nId = WXK_F3; break;
4551 case VK_F4: nId = WXK_F4; break;
4552 case VK_F5: nId = WXK_F5; break;
4553 case VK_F6: nId = WXK_F6; break;
4554 case VK_F7: nId = WXK_F7; break;
4555 case VK_F8: nId = WXK_F8; break;
4556 case VK_F9: nId = WXK_F9; break;
4557 case VK_F10: nId = WXK_F10; break;
4558 case VK_F11: nId = WXK_F11; break;
4559 case VK_F12: nId = WXK_F12; break;
4560 case VK_F13: nId = WXK_F13; break;
4561 case VK_F14: nId = WXK_F14; break;
4562 case VK_F15: nId = WXK_F15; break;
4563 case VK_F16: nId = WXK_F16; break;
4564 case VK_F17: nId = WXK_F17; break;
4565 case VK_F18: nId = WXK_F18; break;
4566 case VK_F19: nId = WXK_F19; break;
4567 case VK_F20: nId = WXK_F20; break;
4568 case VK_F21: nId = WXK_F21; break;
4569 case VK_F22: nId = WXK_F22; break;
4570 case VK_F23: nId = WXK_F23; break;
4571 case VK_F24: nId = WXK_F24; break;
4572 case VK_OEM_1: nId = ';'; break;
4573 case VK_OEM_PLUS: nId = '+'; break;
4574 case VK_OEM_COMMA: nId = ','; break;
4575 case VK_OEM_MINUS: nId = '-'; break;
4576 case VK_OEM_PERIOD: nId = '.'; break;
4577 case VK_OEM_2: nId = '/'; break;
4578 case VK_OEM_3: nId = '~'; break;
4579 case VK_OEM_4: nId = '['; break;
4580 case VK_OEM_5: nId = '\\'; break;
4581 case VK_OEM_6: nId = ']'; break;
4582 case VK_OEM_7: nId = '\''; break;
4583 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
4584 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
4585 default:
4586 {
4587 return 0;
4588 }
4589 }
4590 return nId;
4591 } // end of wxCharCodeOS2ToWX
4592
4593 int wxCharCodeWXToOS2( int nId,
4594 bool* bIsVirtual)
4595 {
4596 int nKeySym = 0;
4597
4598 *bIsVirtual = true;
4599 switch (nId)
4600 {
4601 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
4602 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
4603 case WXK_CONTROL: nKeySym = VK_CTRL; break;
4604 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
4605 case WXK_PRIOR: nKeySym = VK_PAGEUP; break;
4606 case WXK_NEXT : nKeySym = VK_PAGEDOWN; break;
4607 case WXK_END: nKeySym = VK_END; break;
4608 case WXK_HOME : nKeySym = VK_HOME; break;
4609 case WXK_LEFT : nKeySym = VK_LEFT; break;
4610 case WXK_UP: nKeySym = VK_UP; break;
4611 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
4612 case WXK_DOWN : nKeySym = VK_DOWN; break;
4613 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
4614 case WXK_INSERT: nKeySym = VK_INSERT; break;
4615 case WXK_DELETE: nKeySym = VK_DELETE; break;
4616 case WXK_F1: nKeySym = VK_F1; break;
4617 case WXK_F2: nKeySym = VK_F2; break;
4618 case WXK_F3: nKeySym = VK_F3; break;
4619 case WXK_F4: nKeySym = VK_F4; break;
4620 case WXK_F5: nKeySym = VK_F5; break;
4621 case WXK_F6: nKeySym = VK_F6; break;
4622 case WXK_F7: nKeySym = VK_F7; break;
4623 case WXK_F8: nKeySym = VK_F8; break;
4624 case WXK_F9: nKeySym = VK_F9; break;
4625 case WXK_F10: nKeySym = VK_F10; break;
4626 case WXK_F11: nKeySym = VK_F11; break;
4627 case WXK_F12: nKeySym = VK_F12; break;
4628 case WXK_F13: nKeySym = VK_F13; break;
4629 case WXK_F14: nKeySym = VK_F14; break;
4630 case WXK_F15: nKeySym = VK_F15; break;
4631 case WXK_F16: nKeySym = VK_F16; break;
4632 case WXK_F17: nKeySym = VK_F17; break;
4633 case WXK_F18: nKeySym = VK_F18; break;
4634 case WXK_F19: nKeySym = VK_F19; break;
4635 case WXK_F20: nKeySym = VK_F20; break;
4636 case WXK_F21: nKeySym = VK_F21; break;
4637 case WXK_F22: nKeySym = VK_F22; break;
4638 case WXK_F23: nKeySym = VK_F23; break;
4639 case WXK_F24: nKeySym = VK_F24; break;
4640 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
4641 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
4642 default:
4643 {
4644 *bIsVirtual = false;
4645 nKeySym = nId;
4646 break;
4647 }
4648 }
4649 return nKeySym;
4650 } // end of wxCharCodeWXToOS2
4651
4652 wxWindow* wxGetActiveWindow()
4653 {
4654 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
4655
4656 if (hWnd != 0)
4657 {
4658 return wxFindWinFromHandle((WXHWND)hWnd);
4659 }
4660 return NULL;
4661 } // end of wxGetActiveWindow
4662
4663 #ifdef __WXDEBUG__
4664 const wxChar* wxGetMessageName( int nMessage )
4665 {
4666 switch (nMessage)
4667 {
4668 case 0x0000: return wxT("WM_NULL");
4669 case 0x0001: return wxT("WM_CREATE");
4670 case 0x0002: return wxT("WM_DESTROY");
4671 case 0x0004: return wxT("WM_ENABLE");
4672 case 0x0005: return wxT("WM_SHOW");
4673 case 0x0006: return wxT("WM_MOVE");
4674 case 0x0007: return wxT("WM_SIZE");
4675 case 0x0008: return wxT("WM_ADJUSTWINDOWPOS");
4676 case 0x0009: return wxT("WM_CALCVALIDRECTS");
4677 case 0x000A: return wxT("WM_SETWINDOWPARAMS");
4678 case 0x000B: return wxT("WM_QUERYWINDOWPARAMS");
4679 case 0x000C: return wxT("WM_HITTEST");
4680 case 0x000D: return wxT("WM_ACTIVATE");
4681 case 0x000F: return wxT("WM_SETFOCUS");
4682 case 0x0010: return wxT("WM_SETSELECTION");
4683 case 0x0011: return wxT("WM_PPAINT");
4684 case 0x0012: return wxT("WM_PSETFOCUS");
4685 case 0x0013: return wxT("WM_PSYSCOLORCHANGE");
4686 case 0x0014: return wxT("WM_PSIZE");
4687 case 0x0015: return wxT("WM_PACTIVATE");
4688 case 0x0016: return wxT("WM_PCONTROL");
4689 case 0x0020: return wxT("WM_COMMAND");
4690 case 0x0021: return wxT("WM_SYSCOMMAND");
4691 case 0x0022: return wxT("WM_HELP");
4692 case 0x0023: return wxT("WM_PAINT");
4693 case 0x0024: return wxT("WM_TIMER");
4694 case 0x0025: return wxT("WM_SEM1");
4695 case 0x0026: return wxT("WM_SEM2");
4696 case 0x0027: return wxT("WM_SEM3");
4697 case 0x0028: return wxT("WM_SEM4");
4698 case 0x0029: return wxT("WM_CLOSE");
4699 case 0x002A: return wxT("WM_QUIT");
4700 case 0x002B: return wxT("WM_SYSCOLORCHANGE");
4701 case 0x002D: return wxT("WM_SYSVALUECHANGE");
4702 case 0x002E: return wxT("WM_APPTERMINATENOTIFY");
4703 case 0x002F: return wxT("WM_PRESPARAMCHANGED");
4704 // Control notification messages
4705 case 0x0030: return wxT("WM_CONTROL");
4706 case 0x0031: return wxT("WM_VSCROLL");
4707 case 0x0032: return wxT("WM_HSCROLL");
4708 case 0x0033: return wxT("WM_INITMENU");
4709 case 0x0034: return wxT("WM_MENUSELECT");
4710 case 0x0035: return wxT("WM_MENUSEND");
4711 case 0x0036: return wxT("WM_DRAWITEM");
4712 case 0x0037: return wxT("WM_MEASUREITEM");
4713 case 0x0038: return wxT("WM_CONTROLPOINTER");
4714 case 0x003A: return wxT("WM_QUERYDLGCODE");
4715 case 0x003B: return wxT("WM_INITDLG");
4716 case 0x003C: return wxT("WM_SUBSTITUTESTRING");
4717 case 0x003D: return wxT("WM_MATCHMNEMONIC");
4718 case 0x003E: return wxT("WM_SAVEAPPLICATION");
4719 case 0x0129: return wxT("WM_CTLCOLORCHANGE");
4720 case 0x0130: return wxT("WM_QUERYCTLTYPE");
4721 // Frame messages
4722 case 0x0040: return wxT("WM_FLASHWINDOW");
4723 case 0x0041: return wxT("WM_FORMATFRAME");
4724 case 0x0042: return wxT("WM_UPDATEFRAME");
4725 case 0x0043: return wxT("WM_FOCUSCHANGE");
4726 case 0x0044: return wxT("WM_SETBORDERSIZE");
4727 case 0x0045: return wxT("WM_TRACKFRAME");
4728 case 0x0046: return wxT("WM_MINMAXFRAME");
4729 case 0x0047: return wxT("WM_SETICON");
4730 case 0x0048: return wxT("WM_QUERYICON");
4731 case 0x0049: return wxT("WM_SETACCELTABLE");
4732 case 0x004A: return wxT("WM_QUERYACCELTABLE");
4733 case 0x004B: return wxT("WM_TRANSLATEACCEL");
4734 case 0x004C: return wxT("WM_QUERYTRACKINFO");
4735 case 0x004D: return wxT("WM_QUERYBORDERSIZE");
4736 case 0x004E: return wxT("WM_NEXTMENU");
4737 case 0x004F: return wxT("WM_ERASEBACKGROUND");
4738 case 0x0050: return wxT("WM_QUERYFRAMEINFO");
4739 case 0x0051: return wxT("WM_QUERYFOCUSCHAIN");
4740 case 0x0052: return wxT("WM_OWNERPOSCHANGE");
4741 case 0x0053: return wxT("WM_CACLFRAMERECT");
4742 case 0x0055: return wxT("WM_WINDOWPOSCHANGED");
4743 case 0x0056: return wxT("WM_ADJUSTFRAMEPOS");
4744 case 0x0059: return wxT("WM_QUERYFRAMECTLCOUNT");
4745 case 0x005B: return wxT("WM_QUERYHELPINFO");
4746 case 0x005C: return wxT("WM_SETHELPINFO");
4747 case 0x005D: return wxT("WM_ERROR");
4748 case 0x005E: return wxT("WM_REALIZEPALETTE");
4749 // Clipboard messages
4750 case 0x0060: return wxT("WM_RENDERFMT");
4751 case 0x0061: return wxT("WM_RENDERALLFMTS");
4752 case 0x0062: return wxT("WM_DESTROYCLIPBOARD");
4753 case 0x0063: return wxT("WM_PAINTCLIPBOARD");
4754 case 0x0064: return wxT("WM_SIZECLIPBOARD");
4755 case 0x0065: return wxT("WM_HSCROLLCLIPBOARD");
4756 case 0x0066: return wxT("WM_VSCROLLCLIPBOARD");
4757 case 0x0067: return wxT("WM_DRAWCLIPBOARD");
4758 // mouse messages
4759 case 0x0070: return wxT("WM_MOUSEMOVE");
4760 case 0x0071: return wxT("WM_BUTTON1DOWN");
4761 case 0x0072: return wxT("WM_BUTTON1UP");
4762 case 0x0073: return wxT("WM_BUTTON1DBLCLK");
4763 case 0x0074: return wxT("WM_BUTTON2DOWN");
4764 case 0x0075: return wxT("WM_BUTTON2UP");
4765 case 0x0076: return wxT("WM_BUTTON2DBLCLK");
4766 case 0x0077: return wxT("WM_BUTTON3DOWN");
4767 case 0x0078: return wxT("WM_BUTTON3UP");
4768 case 0x0079: return wxT("WM_BUTTON3DBLCLK");
4769 case 0x007D: return wxT("WM_MOUSEMAP");
4770 case 0x007E: return wxT("WM_VRNDISABLED");
4771 case 0x007F: return wxT("WM_VRNENABLED");
4772 case 0x0410: return wxT("WM_CHORD");
4773 case 0x0411: return wxT("WM_BUTTON1MOTIONSTART");
4774 case 0x0412: return wxT("WM_BUTTON1MOTIONEND");
4775 case 0x0413: return wxT("WM_BUTTON1CLICK");
4776 case 0x0414: return wxT("WM_BUTTON2MOTIONSTART");
4777 case 0x0415: return wxT("WM_BUTTON2MOTIONEND");
4778 case 0x0416: return wxT("WM_BUTTON2CLICK");
4779 case 0x0417: return wxT("WM_BUTTON3MOTIONSTART");
4780 case 0x0418: return wxT("WM_BUTTON3MOTIONEND");
4781 case 0x0419: return wxT("WM_BUTTON3CLICK");
4782 case 0x0420: return wxT("WM_BEGINDRAG");
4783 case 0x0421: return wxT("WM_ENDDRAG");
4784 case 0x0422: return wxT("WM_SINGLESELECT");
4785 case 0x0423: return wxT("WM_OPEN");
4786 case 0x0424: return wxT("WM_CONTEXTMENU");
4787 case 0x0425: return wxT("WM_CONTEXTHELP");
4788 case 0x0426: return wxT("WM_TEXTEDIT");
4789 case 0x0427: return wxT("WM_BEGINSELECT");
4790 case 0x0228: return wxT("WM_ENDSELECT");
4791 case 0x0429: return wxT("WM_PICKUP");
4792 case 0x04C0: return wxT("WM_PENFIRST");
4793 case 0x04FF: return wxT("WM_PENLAST");
4794 case 0x0500: return wxT("WM_MMPMFIRST");
4795 case 0x05FF: return wxT("WM_MMPMLAST");
4796 case 0x0600: return wxT("WM_STDDLGFIRST");
4797 case 0x06FF: return wxT("WM_STDDLGLAST");
4798 case 0x0BD0: return wxT("WM_BIDI_FIRST");
4799 case 0x0BFF: return wxT("WM_BIDI_LAST");
4800 // keyboard input
4801 case 0x007A: return wxT("WM_CHAR");
4802 case 0x007B: return wxT("WM_VIOCHAR");
4803 // DDE messages
4804 case 0x00A0: return wxT("WM_DDE_INITIATE");
4805 case 0x00A1: return wxT("WM_DDE_REQUEST");
4806 case 0x00A2: return wxT("WM_DDE_ACK");
4807 case 0x00A3: return wxT("WM_DDE_DATA");
4808 case 0x00A4: return wxT("WM_DDE_ADVISE");
4809 case 0x00A5: return wxT("WM_DDE_UNADVISE");
4810 case 0x00A6: return wxT("WM_DDE_POKE");
4811 case 0x00A7: return wxT("WM_DDE_EXECUTE");
4812 case 0x00A8: return wxT("WM_DDE_TERMINATE");
4813 case 0x00A9: return wxT("WM_DDE_INITIATEACK");
4814 case 0x00AF: return wxT("WM_DDE_LAST");
4815 // Buttons
4816 case 0x0120: return wxT("BM_CLICK");
4817 case 0x0121: return wxT("BM_QUERYCHECKINDEX");
4818 case 0x0122: return wxT("BM_QUERYHILITE");
4819 case 0x0123: return wxT("BM_SETHILITE");
4820 case 0x0124: return wxT("BM_QUERYCHECK");
4821 case 0x0125: return wxT("BM_SETCHECK");
4822 case 0x0126: return wxT("BM_SETDEFAULT");
4823 case 0x0128: return wxT("BM_AUTOSIZE");
4824 // Combo boxes
4825 case 0x029A: return wxT("CBID_LIST");
4826 case 0x029B: return wxT("CBID_EDIT");
4827 case 0x0170: return wxT("CBM_SHOWLIST");
4828 case 0x0171: return wxT("CBM_HILITE");
4829 case 0x0172: return wxT("CBM_ISLISTSHOWING");
4830 // Edit fields
4831 case 0x0140: return wxT("EM_QUERYCHANGED");
4832 case 0x0141: return wxT("EM_QUERYSEL");
4833 case 0x0142: return wxT("EM_SETSEL");
4834 case 0x0143: return wxT("EM_SETTEXTLIMIT");
4835 case 0x0144: return wxT("EM_CUT");
4836 case 0x0145: return wxT("EM_COPY");
4837 case 0x0146: return wxT("EM_CLEAR");
4838 case 0x0147: return wxT("EM_PASTE");
4839 case 0x0148: return wxT("EM_QUERYFIRSTCHAR");
4840 case 0x0149: return wxT("EM_SETFIRSTCHAR");
4841 case 0x014A: return wxT("EM_QUERYREADONLY");
4842 case 0x014B: return wxT("EM_SETREADONLY");
4843 case 0x014C: return wxT("EM_SETINSERTMODE");
4844 // Listboxes
4845 case 0x0160: return wxT("LM_QUERYITEMCOUNT");
4846 case 0x0161: return wxT("LM_INSERTITEM");
4847 case 0x0162: return wxT("LM_SETOPENINDEX");
4848 case 0x0163: return wxT("LM_DELETEITEM");
4849 case 0x0164: return wxT("LM_SELECTITEM");
4850 case 0x0165: return wxT("LM_QUERYSELECTION");
4851 case 0x0166: return wxT("LM_SETITEMTEXT");
4852 case 0x0167: return wxT("LM_QUERYITEMTEXTLENGTH");
4853 case 0x0168: return wxT("LM_QUERYITEMTEXT");
4854 case 0x0169: return wxT("LM_SETITEMHANDLE");
4855 case 0x016A: return wxT("LM_QUERYITEMHANDLE");
4856 case 0x016B: return wxT("LM_SEARCHSTRING");
4857 case 0x016C: return wxT("LM_SETITEMHEIGHT");
4858 case 0x016D: return wxT("LM_QUERYTOPINDEX");
4859 case 0x016E: return wxT("LM_DELETEALL");
4860 case 0x016F: return wxT("LM_INSERTMULITEMS");
4861 case 0x0660: return wxT("LM_SETITEMWIDTH");
4862 // Menus
4863 case 0x0180: return wxT("MM_INSERTITEM");
4864 case 0x0181: return wxT("MM_DELETEITEM");
4865 case 0x0182: return wxT("MM_QUERYITEM");
4866 case 0x0183: return wxT("MM_SETITEM");
4867 case 0x0184: return wxT("MM_QUERYITEMCOUNT");
4868 case 0x0185: return wxT("MM_STARTMENUMODE");
4869 case 0x0186: return wxT("MM_ENDMENUMODE");
4870 case 0x0188: return wxT("MM_REMOVEITEM");
4871 case 0x0189: return wxT("MM_SELECTITEM");
4872 case 0x018A: return wxT("MM_QUERYSELITEMID");
4873 case 0x018B: return wxT("MM_QUERYITEMTEXT");
4874 case 0x018C: return wxT("MM_QUERYITEMTEXTLENGTH");
4875 case 0x018D: return wxT("MM_SETITEMHANDLE");
4876 case 0x018E: return wxT("MM_SETITEMTEXT");
4877 case 0x018F: return wxT("MM_ITEMPOSITIONFROMID");
4878 case 0x0190: return wxT("MM_ITEMIDFROMPOSITION");
4879 case 0x0191: return wxT("MM_QUERYITEMATTR");
4880 case 0x0192: return wxT("MM_SETITEMATTR");
4881 case 0x0193: return wxT("MM_ISITEMVALID");
4882 case 0x0194: return wxT("MM_QUERYITEMRECT");
4883 case 0x0431: return wxT("MM_QUERYDEFAULTITEMID");
4884 case 0x0432: return wxT("MM_SETDEFAULTITEMID");
4885 // Scrollbars
4886 case 0x01A0: return wxT("SBM_SETSCROLLBAR");
4887 case 0x01A1: return wxT("SBM_SETPOS");
4888 case 0x01A2: return wxT("SBM_QUERYPOS");
4889 case 0x01A3: return wxT("SBM_QUERYRANGE");
4890 case 0x01A6: return wxT("SBM_SETTHUMBSIZE");
4891
4892 // Help messages
4893 case 0x0F00: return wxT("WM_HELPBASE");
4894 case 0x0FFF: return wxT("WM_HELPTOP");
4895 // Beginning of user defined messages
4896 case 0x1000: return wxT("WM_USER");
4897
4898 // wxWidgets user defined types
4899
4900 // listview
4901 // case 0x1000 + 0: return wxT("LVM_GETBKCOLOR");
4902 case 0x1000 + 1: return wxT("LVM_SETBKCOLOR");
4903 case 0x1000 + 2: return wxT("LVM_GETIMAGELIST");
4904 case 0x1000 + 3: return wxT("LVM_SETIMAGELIST");
4905 case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT");
4906 case 0x1000 + 5: return wxT("LVM_GETITEMA");
4907 case 0x1000 + 75: return wxT("LVM_GETITEMW");
4908 case 0x1000 + 6: return wxT("LVM_SETITEMA");
4909 case 0x1000 + 76: return wxT("LVM_SETITEMW");
4910 case 0x1000 + 7: return wxT("LVM_INSERTITEMA");
4911 case 0x1000 + 77: return wxT("LVM_INSERTITEMW");
4912 case 0x1000 + 8: return wxT("LVM_DELETEITEM");
4913 case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS");
4914 case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK");
4915 case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK");
4916 case 0x1000 + 12: return wxT("LVM_GETNEXTITEM");
4917 case 0x1000 + 13: return wxT("LVM_FINDITEMA");
4918 case 0x1000 + 83: return wxT("LVM_FINDITEMW");
4919 case 0x1000 + 14: return wxT("LVM_GETITEMRECT");
4920 case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION");
4921 case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION");
4922 case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA");
4923 case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW");
4924 case 0x1000 + 18: return wxT("LVM_HITTEST");
4925 case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE");
4926 case 0x1000 + 20: return wxT("LVM_SCROLL");
4927 case 0x1000 + 21: return wxT("LVM_REDRAWITEMS");
4928 case 0x1000 + 22: return wxT("LVM_ARRANGE");
4929 case 0x1000 + 23: return wxT("LVM_EDITLABELA");
4930 case 0x1000 + 118: return wxT("LVM_EDITLABELW");
4931 case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL");
4932 case 0x1000 + 25: return wxT("LVM_GETCOLUMNA");
4933 case 0x1000 + 95: return wxT("LVM_GETCOLUMNW");
4934 case 0x1000 + 26: return wxT("LVM_SETCOLUMNA");
4935 case 0x1000 + 96: return wxT("LVM_SETCOLUMNW");
4936 case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA");
4937 case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW");
4938 case 0x1000 + 28: return wxT("LVM_DELETECOLUMN");
4939 case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH");
4940 case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH");
4941 case 0x1000 + 31: return wxT("LVM_GETHEADER");
4942 case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE");
4943 case 0x1000 + 34: return wxT("LVM_GETVIEWRECT");
4944 case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR");
4945 case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR");
4946 case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR");
4947 case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR");
4948 case 0x1000 + 39: return wxT("LVM_GETTOPINDEX");
4949 case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE");
4950 case 0x1000 + 41: return wxT("LVM_GETORIGIN");
4951 case 0x1000 + 42: return wxT("LVM_UPDATE");
4952 case 0x1000 + 43: return wxT("LVM_SETITEMSTATE");
4953 case 0x1000 + 44: return wxT("LVM_GETITEMSTATE");
4954 case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA");
4955 case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW");
4956 case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA");
4957 case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW");
4958 case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT");
4959 case 0x1000 + 48: return wxT("LVM_SORTITEMS");
4960 case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32");
4961 case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT");
4962 case 0x1000 + 51: return wxT("LVM_GETITEMSPACING");
4963 case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA");
4964 case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW");
4965 case 0x1000 + 53: return wxT("LVM_SETICONSPACING");
4966 case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE");
4967 case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE");
4968 case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT");
4969 case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST");
4970 case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY");
4971 case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY");
4972 case 0x1000 + 60: return wxT("LVM_SETHOTITEM");
4973 case 0x1000 + 61: return wxT("LVM_GETHOTITEM");
4974 case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR");
4975 case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR");
4976 case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT");
4977 case 0x1000 + 65: return wxT("LVM_SETWORKAREA");
4978
4979 // tree view
4980 case 0x1100 + 0: return wxT("TVM_INSERTITEMA");
4981 case 0x1100 + 50: return wxT("TVM_INSERTITEMW");
4982 case 0x1100 + 1: return wxT("TVM_DELETEITEM");
4983 case 0x1100 + 2: return wxT("TVM_EXPAND");
4984 case 0x1100 + 4: return wxT("TVM_GETITEMRECT");
4985 case 0x1100 + 5: return wxT("TVM_GETCOUNT");
4986 case 0x1100 + 6: return wxT("TVM_GETINDENT");
4987 case 0x1100 + 7: return wxT("TVM_SETINDENT");
4988 case 0x1100 + 8: return wxT("TVM_GETIMAGELIST");
4989 case 0x1100 + 9: return wxT("TVM_SETIMAGELIST");
4990 case 0x1100 + 10: return wxT("TVM_GETNEXTITEM");
4991 case 0x1100 + 11: return wxT("TVM_SELECTITEM");
4992 case 0x1100 + 12: return wxT("TVM_GETITEMA");
4993 case 0x1100 + 62: return wxT("TVM_GETITEMW");
4994 case 0x1100 + 13: return wxT("TVM_SETITEMA");
4995 case 0x1100 + 63: return wxT("TVM_SETITEMW");
4996 case 0x1100 + 14: return wxT("TVM_EDITLABELA");
4997 case 0x1100 + 65: return wxT("TVM_EDITLABELW");
4998 case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL");
4999 case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT");
5000 case 0x1100 + 17: return wxT("TVM_HITTEST");
5001 case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE");
5002 case 0x1100 + 19: return wxT("TVM_SORTCHILDREN");
5003 case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE");
5004 case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB");
5005 case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW");
5006 case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA");
5007 case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW");
5008 case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS");
5009 case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS");
5010
5011 // header
5012 case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT");
5013 case 0x1200 + 1: return wxT("HDM_INSERTITEMA");
5014 case 0x1200 + 10: return wxT("HDM_INSERTITEMW");
5015 case 0x1200 + 2: return wxT("HDM_DELETEITEM");
5016 case 0x1200 + 3: return wxT("HDM_GETITEMA");
5017 case 0x1200 + 11: return wxT("HDM_GETITEMW");
5018 case 0x1200 + 4: return wxT("HDM_SETITEMA");
5019 case 0x1200 + 12: return wxT("HDM_SETITEMW");
5020 case 0x1200 + 5: return wxT("HDM_LAYOUT");
5021 case 0x1200 + 6: return wxT("HDM_HITTEST");
5022 case 0x1200 + 7: return wxT("HDM_GETITEMRECT");
5023 case 0x1200 + 8: return wxT("HDM_SETIMAGELIST");
5024 case 0x1200 + 9: return wxT("HDM_GETIMAGELIST");
5025 case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX");
5026 case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE");
5027 case 0x1200 + 17: return wxT("HDM_GETORDERARRAY");
5028 case 0x1200 + 18: return wxT("HDM_SETORDERARRAY");
5029 case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER");
5030
5031 // tab control
5032 case 0x1300 + 2: return wxT("TCM_GETIMAGELIST");
5033 case 0x1300 + 3: return wxT("TCM_SETIMAGELIST");
5034 case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT");
5035 case 0x1300 + 5: return wxT("TCM_GETITEMA");
5036 case 0x1300 + 60: return wxT("TCM_GETITEMW");
5037 case 0x1300 + 6: return wxT("TCM_SETITEMA");
5038 case 0x1300 + 61: return wxT("TCM_SETITEMW");
5039 case 0x1300 + 7: return wxT("TCM_INSERTITEMA");
5040 case 0x1300 + 62: return wxT("TCM_INSERTITEMW");
5041 case 0x1300 + 8: return wxT("TCM_DELETEITEM");
5042 case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS");
5043 case 0x1300 + 10: return wxT("TCM_GETITEMRECT");
5044 case 0x1300 + 11: return wxT("TCM_GETCURSEL");
5045 case 0x1300 + 12: return wxT("TCM_SETCURSEL");
5046 case 0x1300 + 13: return wxT("TCM_HITTEST");
5047 case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA");
5048 case 0x1300 + 40: return wxT("TCM_ADJUSTRECT");
5049 case 0x1300 + 41: return wxT("TCM_SETITEMSIZE");
5050 case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE");
5051 case 0x1300 + 43: return wxT("TCM_SETPADDING");
5052 case 0x1300 + 44: return wxT("TCM_GETROWCOUNT");
5053 case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS");
5054 case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS");
5055 case 0x1300 + 47: return wxT("TCM_GETCURFOCUS");
5056 case 0x1300 + 48: return wxT("TCM_SETCURFOCUS");
5057 case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH");
5058 case 0x1300 + 50: return wxT("TCM_DESELECTALL");
5059
5060 // toolbar
5061 case WM_USER+1000+1: return wxT("TB_ENABLEBUTTON");
5062 case WM_USER+1000+2: return wxT("TB_CHECKBUTTON");
5063 case WM_USER+1000+3: return wxT("TB_PRESSBUTTON");
5064 case WM_USER+1000+4: return wxT("TB_HIDEBUTTON");
5065 case WM_USER+1000+5: return wxT("TB_INDETERMINATE");
5066 case WM_USER+1000+9: return wxT("TB_ISBUTTONENABLED");
5067 case WM_USER+1000+10: return wxT("TB_ISBUTTONCHECKED");
5068 case WM_USER+1000+11: return wxT("TB_ISBUTTONPRESSED");
5069 case WM_USER+1000+12: return wxT("TB_ISBUTTONHIDDEN");
5070 case WM_USER+1000+13: return wxT("TB_ISBUTTONINDETERMINATE");
5071 case WM_USER+1000+17: return wxT("TB_SETSTATE");
5072 case WM_USER+1000+18: return wxT("TB_GETSTATE");
5073 case WM_USER+1000+19: return wxT("TB_ADDBITMAP");
5074 case WM_USER+1000+20: return wxT("TB_ADDBUTTONS");
5075 case WM_USER+1000+21: return wxT("TB_INSERTBUTTON");
5076 case WM_USER+1000+22: return wxT("TB_DELETEBUTTON");
5077 case WM_USER+1000+23: return wxT("TB_GETBUTTON");
5078 case WM_USER+1000+24: return wxT("TB_BUTTONCOUNT");
5079 case WM_USER+1000+25: return wxT("TB_COMMANDTOINDEX");
5080 case WM_USER+1000+26: return wxT("TB_SAVERESTOREA");
5081 case WM_USER+1000+76: return wxT("TB_SAVERESTOREW");
5082 case WM_USER+1000+27: return wxT("TB_CUSTOMIZE");
5083 case WM_USER+1000+28: return wxT("TB_ADDSTRINGA");
5084 case WM_USER+1000+77: return wxT("TB_ADDSTRINGW");
5085 case WM_USER+1000+29: return wxT("TB_GETITEMRECT");
5086 case WM_USER+1000+30: return wxT("TB_BUTTONSTRUCTSIZE");
5087 case WM_USER+1000+31: return wxT("TB_SETBUTTONSIZE");
5088 case WM_USER+1000+32: return wxT("TB_SETBITMAPSIZE");
5089 case WM_USER+1000+33: return wxT("TB_AUTOSIZE");
5090 case WM_USER+1000+35: return wxT("TB_GETTOOLTIPS");
5091 case WM_USER+1000+36: return wxT("TB_SETTOOLTIPS");
5092 case WM_USER+1000+37: return wxT("TB_SETPARENT");
5093 case WM_USER+1000+39: return wxT("TB_SETROWS");
5094 case WM_USER+1000+40: return wxT("TB_GETROWS");
5095 case WM_USER+1000+42: return wxT("TB_SETCMDID");
5096 case WM_USER+1000+43: return wxT("TB_CHANGEBITMAP");
5097 case WM_USER+1000+44: return wxT("TB_GETBITMAP");
5098 case WM_USER+1000+45: return wxT("TB_GETBUTTONTEXTA");
5099 case WM_USER+1000+75: return wxT("TB_GETBUTTONTEXTW");
5100 case WM_USER+1000+46: return wxT("TB_REPLACEBITMAP");
5101 case WM_USER+1000+47: return wxT("TB_SETINDENT");
5102 case WM_USER+1000+48: return wxT("TB_SETIMAGELIST");
5103 case WM_USER+1000+49: return wxT("TB_GETIMAGELIST");
5104 case WM_USER+1000+50: return wxT("TB_LOADIMAGES");
5105 case WM_USER+1000+51: return wxT("TB_GETRECT");
5106 case WM_USER+1000+52: return wxT("TB_SETHOTIMAGELIST");
5107 case WM_USER+1000+53: return wxT("TB_GETHOTIMAGELIST");
5108 case WM_USER+1000+54: return wxT("TB_SETDISABLEDIMAGELIST");
5109 case WM_USER+1000+55: return wxT("TB_GETDISABLEDIMAGELIST");
5110 case WM_USER+1000+56: return wxT("TB_SETSTYLE");
5111 case WM_USER+1000+57: return wxT("TB_GETSTYLE");
5112 case WM_USER+1000+58: return wxT("TB_GETBUTTONSIZE");
5113 case WM_USER+1000+59: return wxT("TB_SETBUTTONWIDTH");
5114 case WM_USER+1000+60: return wxT("TB_SETMAXTEXTROWS");
5115 case WM_USER+1000+61: return wxT("TB_GETTEXTROWS");
5116 case WM_USER+1000+41: return wxT("TB_GETBITMAPFLAGS");
5117 }
5118
5119 static wxString s_szBuf;
5120 s_szBuf.Printf(wxT("<unknown message = %d>"), nMessage);
5121 return s_szBuf.c_str();
5122
5123 } // end of wxGetMessageName
5124
5125 #endif // __WXDEBUG__
5126
5127 // Unused?
5128 #if 0
5129 static void TranslateKbdEventToMouse(
5130 wxWindow* pWin
5131 , int* pX
5132 , int* pY
5133 , ULONG* pFlags
5134 )
5135 {
5136 //
5137 // Construct the key mask
5138 ULONG& fwKeys = *pFlags;
5139
5140 fwKeys = VK_BUTTON2;
5141 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
5142 fwKeys |= VK_CTRL;
5143 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
5144 fwKeys |= VK_SHIFT;
5145
5146 //
5147 // Simulate right mouse button click
5148 //
5149 POINTL vPoint;
5150
5151 ::WinQueryMsgPos(vHabmain, &vPoint);
5152 *pX = vPoint.x;
5153 *pY = vPoint.y;
5154
5155 pWin->ScreenToClient(pX, pY);
5156 } // end of TranslateKbdEventToMouse
5157 #endif
5158
5159 // Find the wxWindow at the current mouse position, returning the mouse
5160 // position.
5161 wxWindow* wxFindWindowAtPointer(wxPoint& WXUNUSED(rPt))
5162 {
5163 return wxFindWindowAtPoint(wxGetMousePosition());
5164 }
5165
5166 wxWindow* wxFindWindowAtPoint(const wxPoint& rPt)
5167 {
5168 POINTL vPt2;
5169
5170 vPt2.x = rPt.x;
5171 vPt2.y = rPt.y;
5172
5173 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
5174 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
5175 HWND hWnd = hWndHit;
5176
5177 //
5178 // Try to find a window with a wxWindow associated with it
5179 //
5180 while (!pWin && (hWnd != 0))
5181 {
5182 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
5183 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
5184 }
5185 return pWin;
5186 }
5187
5188 // Get the current mouse position.
5189 wxPoint wxGetMousePosition()
5190 {
5191 POINTL vPt;
5192
5193 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
5194 return wxPoint(vPt.x, vPt.y);
5195 }
5196
5197 wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin,
5198 short* WXUNUSED(pnX),
5199 short* WXUNUSED(pnY) )
5200 {
5201 HWND hWnd = GetHwndOf(pWin);
5202 HWND hWndUnderMouse;
5203 POINTL vPoint;
5204 BOOL rcEnabled = FALSE;
5205 BOOL rcVisible = FALSE;
5206
5207 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
5208 hWndUnderMouse = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
5209 if (hWndUnderMouse != HWND_DESKTOP)
5210 {
5211 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5212
5213 if (pWinUnderMouse)
5214 {
5215 wxWindowList::compatibility_iterator current = pWinUnderMouse->GetChildren().GetFirst();
5216 wxWindow* pGrandChild = NULL;
5217 RECTL vRect;
5218 POINTL vPoint2;
5219
5220 ::WinMapWindowPoints(HWND_DESKTOP, hWndUnderMouse, &vPoint, 1);
5221 //
5222 // Find a child window mouse might be under
5223 //
5224 while (current)
5225 {
5226 wxWindow* pChild = current->GetData();
5227
5228 vPoint2.x = vPoint.x;
5229 vPoint2.y = vPoint.y;
5230 ::WinMapWindowPoints(hWndUnderMouse, pChild->GetHWND(), &vPoint2, 1);
5231 ::WinQueryWindowRect(pChild->GetHWND(), &vRect);
5232 if (::WinPtInRect(vHabmain, &vRect, &vPoint2))
5233 {
5234 if (pChild->IsTopLevel())
5235 {
5236 POINTL vPoint3;
5237 wxWindowList::compatibility_iterator current2 =pChild->GetChildren().GetFirst();
5238
5239 while (current2)
5240 {
5241 wxWindow* pGrandChild = current2->GetData();
5242
5243 vPoint3.x = vPoint2.x;
5244 vPoint3.y = vPoint2.y;
5245 ::WinMapWindowPoints( pChild->GetHWND()
5246 ,pGrandChild->GetHWND()
5247 ,&vPoint3
5248 ,1
5249 );
5250 ::WinQueryWindowRect(pGrandChild->GetHWND(), &vRect);
5251 if (::WinPtInRect(vHabmain, &vRect, &vPoint3))
5252 {
5253 hWndUnderMouse = GetHwndOf(pGrandChild);
5254 pWinUnderMouse = pGrandChild;
5255 break;
5256 }
5257 current2 = current2->GetNext();
5258 }
5259 if (pGrandChild)
5260 break;
5261 }
5262 hWndUnderMouse = GetHwndOf(pChild);
5263 pWinUnderMouse = pChild;
5264 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5265 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5266 if (rcVisible && rcEnabled)
5267 break;
5268 }
5269 current = current->GetNext();
5270 }
5271 }
5272 }
5273 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5274 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5275
5276
5277 //
5278 // Check that we have a child window which is susceptible to receive mouse
5279 // events: for this it must be shown and enabled
5280 //
5281 if ( hWndUnderMouse &&
5282 hWndUnderMouse != hWnd &&
5283 rcVisible && rcEnabled)
5284 {
5285 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5286
5287 if (pWinUnderMouse)
5288 {
5289 //
5290 // Translate the mouse coords to the other window coords
5291 //
5292 pWin = pWinUnderMouse;
5293 }
5294 }
5295 return pWin;
5296 } // end of FindWindowForMouseEvent