]> git.saurik.com Git - wxWidgets.git/blob - src/msw/display.cpp
Only send two EVT_BUTTON events when double clicking a button, not three
[wxWidgets.git] / src / msw / display.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: display.cpp
3 // Purpose: MSW Implementation of wxDisplay class
4 // Author: Royce Mitchell III
5 // Modified by:
6 // Created: 06/21/02
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "display.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_DISPLAY
32
33 #ifndef WX_PRECOMP
34 #include "wx/dynarray.h"
35 #endif
36
37 #include "wx/display.h"
38
39 // the following define is necessary to access the multi-monitor function
40 // declarations in a manner safe to use w/ Windows 95
41 // JACS: not used for now until we're clear about the legality
42 // of distributing multimon.h. Meanwhile you can download the file
43 // yourself from:
44 // http://www.microsoft.com/msj/0697/monitor/monitortextfigs.htm#fig4
45
46 #if 0
47 #define COMPILE_MULTIMON_STUBS
48 #include "wx/msw/multimon.h"
49 #endif
50
51 // ---------------------------------------------------------------------------
52 // constants
53 // ---------------------------------------------------------------------------
54
55 // ---------------------------------------------------------------------------
56 // private functions
57 // ---------------------------------------------------------------------------
58
59 void wxmswInitDisplayRectArray();
60
61 // ----------------------------------------------------------------------------
62 // private classes
63 // ----------------------------------------------------------------------------
64
65 class wxmswDisplayInfo;
66
67 WX_DECLARE_OBJARRAY(wxmswDisplayInfo, wxmswDisplayInfoArray);
68
69 class wxmswDisplayInfo
70 {
71 public:
72 HMONITOR m_hmon;
73 DISPLAY_DEVICE m_dd;
74 wxRect m_rect;
75 int m_depth;
76 };
77
78 wxmswDisplayInfoArray* g_wxmswDisplayInfoArray = 0;
79
80 #include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
81 WX_DEFINE_OBJARRAY(wxmswDisplayInfoArray);
82
83 // ===========================================================================
84 // implementation
85 // ===========================================================================
86
87 BOOL CALLBACK wxmswMonitorEnumProc (
88 HMONITOR hMonitor, // handle to display monitor
89 HDC hdcMonitor, // handle to monitor-appropriate device context
90 LPRECT lprcMonitor, // pointer to monitor intersection rectangle
91 LPARAM dwData // data passed from EnumDisplayMonitors
92 )
93 {
94 wxmswDisplayInfo* info = new wxmswDisplayInfo();
95 info->m_hmon = hMonitor;
96 info->m_rect.SetX ( lprcMonitor->left );
97 info->m_rect.SetY ( lprcMonitor->top );
98 info->m_rect.SetWidth ( lprcMonitor->right - lprcMonitor->left );
99 info->m_rect.SetHeight ( lprcMonitor->bottom - lprcMonitor->top );
100 // now add this monitor to the array
101 g_wxmswDisplayInfoArray->Add ( info );
102
103 return TRUE; // continue the enumeration
104 }
105
106 class wxmswDisplayModule : public wxModule
107 {
108 DECLARE_DYNAMIC_CLASS(wxmswDisplayModule)
109 public:
110 wxmswDisplayModule() {}
111 bool OnInit();
112 void OnExit();
113 };
114
115 IMPLEMENT_DYNAMIC_CLASS(wxmswDisplayModule, wxModule)
116
117 bool wxmswDisplayModule::OnInit()
118 {
119 g_wxmswDisplayInfoArray = new wxmswDisplayInfoArray();
120 if ( !g_wxmswDisplayInfoArray )
121 {
122 wxFAIL_MSG(wxT("Couldn't allocate array for display information"));
123 return FALSE;
124 }
125
126 // Royce3: I'm assuming that the monitor's are enumerated in the same
127 // order as the calls to EnumDisplayDevices below. We shall soon see
128 // if that assumption is correct.
129 if ( !EnumDisplayMonitors ( NULL, NULL, wxmswMonitorEnumProc, 0 ) )
130 wxLogLastError(wxT("EnumDisplayMonitors"));
131
132 size_t iDevNum = 0, count = g_wxmswDisplayInfoArray->Count();
133 while ( iDevNum < count )
134 {
135 wxmswDisplayInfo& info = (*g_wxmswDisplayInfoArray)[iDevNum];
136
137 // MSDN: Before calling EnumDisplayDevices, you must initialize the cb
138 // member of DISPLAY_DEVICE to the size, in bytes, of DISPLAY_DEVICE
139 info.m_dd.cb = sizeof(info.m_dd);
140
141 if ( !EnumDisplayDevices ( NULL, iDevNum, &info.m_dd, 0 ) )
142 wxLogLastError(wxT("EnumDisplayDevices"));
143
144 // get this display's Depth
145 DEVMODE devmode;
146 memset ( &devmode, 0, sizeof(devmode) );
147
148 // MSDN: Before calling EnumDisplaySettings, set the dmSize member to
149 // sizeof(DEVMODE), and set the dmDriverExtra member to indicate the size,
150 // in bytes, of the additional space available to receive private
151 // driver-data.
152 devmode.dmSize = sizeof(devmode);
153 devmode.dmDriverExtra = 0;
154
155 if ( !EnumDisplaySettings ( info.m_dd.DeviceName, ENUM_CURRENT_SETTINGS, &devmode ) )
156 {
157 wxLogLastError(wxT("EnumDisplaySettings"));
158 devmode.dmFields = 0;
159 }
160
161 if ( !(devmode.dmFields&DM_BITSPERPEL) )
162 info.m_depth = -1;
163 else
164 info.m_depth = devmode.dmBitsPerPel;
165
166
167 iDevNum++;
168 }
169 return TRUE;
170 }
171
172 void wxmswDisplayModule::OnExit()
173 {
174 size_t count = g_wxmswDisplayInfoArray->Count();
175 while ( count-- )
176 {
177 wxmswDisplayInfo* info = g_wxmswDisplayInfoArray->Detach ( count );
178 delete info;
179 }
180 delete g_wxmswDisplayInfoArray;
181 g_wxmswDisplayInfoArray = 0;
182 }
183
184 // ---------------------------------------------------------------------------
185 // wxDisplay
186 // ---------------------------------------------------------------------------
187
188 size_t wxDisplayBase::GetCount()
189 {
190 return GetSystemMetrics ( SM_CMONITORS );
191 }
192
193 int wxDisplayBase::GetFromPoint ( const wxPoint& pt )
194 {
195 POINT pt2;
196 pt2.x = pt.x;
197 pt2.y = pt.y;
198
199 HMONITOR hmon = MonitorFromPoint ( pt2, 0 );
200 if ( !hmon )
201 return -1;
202 size_t count = wxDisplayBase::GetCount(), index;
203
204 for ( index = 0; index < count; index++ )
205 {
206 if ( hmon == (*g_wxmswDisplayInfoArray)[index].m_hmon )
207 return index;
208 }
209
210 return -1;
211 }
212
213 wxDisplay::wxDisplay ( size_t index ) : wxDisplayBase ( index )
214 {
215 }
216
217 wxRect wxDisplay::GetGeometry() const
218 {
219 return (*g_wxmswDisplayInfoArray)[m_index].m_rect;
220 }
221
222 int wxDisplay::GetDepth() const
223 {
224 return (*g_wxmswDisplayInfoArray)[m_index].m_depth;
225 }
226
227 wxString wxDisplay::GetName() const
228 {
229 return wxString ( (*g_wxmswDisplayInfoArray)[m_index].m_dd.DeviceName );
230 }
231
232 #endif//wxUSE_DISPLAY