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