]>
Commit | Line | Data |
---|---|---|
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 |