1 /* AbiSource Program Utilities
2  * Copyright (C) 1998 AbiSource, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301 USA.
18  */
19 
20 #include <windows.h>
21 #include <winspool.h>
22 #include "ut_debugmsg.h"
23 #include "ut_assert.h"
24 #include "ut_locale.h"
25 #include "ut_iconv.h"
26 #include "ut_Win32OS.h"
27 
28 /*!
29  Returns Windows's OSVERSIONINFO structure
30  */
UT_GetWinVersion(void)31 OSVERSIONINFOW& UT_GetWinVersion(void)
32 {
33 	static bool bInitialized = false;
34 	static OSVERSIONINFOW os;
35 
36 	if (!bInitialized)
37 	{
38 		os.dwOSVersionInfoSize = sizeof(os);
39 		UT_DebugOnly<BOOL> bSuccess = GetVersionExW(&os);
40 		UT_ASSERT(bSuccess);
41 		bInitialized = true;
42 	}
43 
44 	return os;
45 }
46 
47 /*!
48  Return true if we're running on Windows Vista, false otherwise
49  */
UT_IsWinVista(void)50 bool UT_IsWinVista(void)
51 {
52 	return (UT_GetWinVersion().dwPlatformId == VER_PLATFORM_WIN32_NT
53 		 && UT_GetWinVersion().dwMajorVersion >= 6);
54 }
55 
56 /*!
57  Return true if we're running on Windows NT, false otherwise
58  */
UT_IsWinNT(void)59 bool UT_IsWinNT(void)
60 {
61 	return UT_GetWinVersion().dwPlatformId == VER_PLATFORM_WIN32_NT;
62 }
63 
64 /*!
65  Return true if we're running on Windows 2000, false otherwise
66  */
UT_IsWin2K(void)67 bool UT_IsWin2K(void)
68 {
69 	return (UT_GetWinVersion().dwPlatformId == VER_PLATFORM_WIN32_NT
70 		 && UT_GetWinVersion().dwMajorVersion >= 5);
71 }
72 
73 /*!
74  Return true if we're running on Windows 95, false otherwise
75  */
UT_IsWin95(void)76 bool UT_IsWin95(void)
77 {
78 	return (UT_GetWinVersion().dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
79 		 && UT_GetWinVersion().dwMajorVersion == 4 && UT_GetWinVersion().dwMinorVersion == 0);
80 }
81 
82 /*****************************************************************/
83 
84 /*!
85  This function loads and locks a dialog template resource.
86 
87  \param hinst
88  \param lpszResName Name of the resource
89 
90  Returns the address of the locked resource.
91  The caller is responsible for any unlocking/releasing necessary.
92  This function is used by the various tabbed dialogs to load
93  the sub-dialogs.
94  */
UT_LockDlgRes(HINSTANCE hinst,LPCWSTR lpszResName)95 DLGTEMPLATE * WINAPI UT_LockDlgRes(HINSTANCE hinst, LPCWSTR lpszResName)
96 {
97     HRSRC hrsrc = FindResourceW(NULL, lpszResName,  (LPWSTR)RT_DIALOG);
98     HGLOBAL hglb = LoadResource(hinst, hrsrc);
99     return (DLGTEMPLATE *) LockResource(hglb);
100 }
101 
102 /*!
103     This code is based on function by Philippe Randour <philippe_randour at hotmail dot
104     com> and was found at http://bdn.borland.com/article/0,1410,28000,00.html
105 
106     (It is real pain that such an elementary task should be so hard)
107 
108     The caller must g_free the returned pointer when no longer needed
109 */
110 
111 
112 #define GETDEFAULTPRINTER "GetDefaultPrinterW"
113 
114 
UT_GetDefaultPrinterName()115 wchar_t * UT_GetDefaultPrinterName()
116 {
117 	UT_uint32 iBufferSize = 128; // will become 2x bigger immediately in the loop
118 	wchar_t * pPrinterName = NULL;
119 	DWORD rc;
120 
121 	do
122 	{
123 		iBufferSize *= 2;
124 
125 		if(pPrinterName)
126 			g_free(pPrinterName);
127 
128 		pPrinterName = (wchar_t *) UT_calloc(sizeof(wchar_t),iBufferSize);
129 		UT_return_val_if_fail( pPrinterName, NULL );
130 
131 		// the method of obtaining the name is version specific ...
132 		OSVERSIONINFOW osvi;
133 		DWORD iNeeded, iReturned, iBuffSize;
134 		LPPRINTER_INFO_5W pPrinterInfo;
135 		wchar_t* p;
136 
137 		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
138 		GetVersionExW(&osvi);
139 
140 		if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
141 		{
142 			// get size of the buffer needed to call enum printers
143 			if (!EnumPrintersW(PRINTER_ENUM_DEFAULT,NULL,5,NULL,0,&iNeeded,&iReturned))
144 			{
145 				if ((rc = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
146 				{
147 					return NULL;
148 				}
149 			}
150 
151 			// allocate the buffer
152 			if ((pPrinterInfo = (LPPRINTER_INFO_5W)LocalAlloc(LPTR,iNeeded)) == NULL)
153 			{
154 				rc = GetLastError();
155 			}
156 			else
157 			{
158 				// now get the default printer
159 				if (!EnumPrintersW(PRINTER_ENUM_DEFAULT,NULL,5,
160 								  (LPBYTE) pPrinterInfo,iNeeded,&iNeeded,&iReturned))
161 				{
162 					rc = GetLastError();
163 				}
164 				else
165 				{
166 					if (iReturned > 0)
167 					{
168 						// here we copy the name to our own buffer
169 						if ((DWORD) wcslen(pPrinterInfo->pPrinterName) > iBufferSize-1)
170 						{
171 							rc = ERROR_INSUFFICIENT_BUFFER;
172 						}
173 						else
174 						{
175 							wcscpy(pPrinterName,pPrinterInfo->pPrinterName);
176 							rc = ERROR_SUCCESS;
177 						}
178 					}
179 					else
180 					{
181 						*pPrinterName = '0';
182 						rc = ERROR_SUCCESS;
183 					}
184 				}
185 
186 				LocalFree(pPrinterInfo);
187 			}
188 		}
189 		else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
190 		{
191 			if (osvi.dwMajorVersion >= 5) /* Windows 2000 or later */
192 			{
193 				iBuffSize = iBufferSize;
194 
195 				HMODULE hWinSpool = LoadLibraryW(L"winspool.drv");
196 				if (!hWinSpool)
197 					return NULL;
198 
199 				HRESULT (WINAPI * fnGetDefaultPrinter)(LPWSTR, LPDWORD) =
200 					(HRESULT (WINAPI * )(LPWSTR, LPDWORD)) GetProcAddress(hWinSpool, GETDEFAULTPRINTER);
201 
202 				if (!fnGetDefaultPrinter)
203 				{
204 					FreeLibrary(hWinSpool);
205 					return NULL;
206 				}
207 
208                 bool i =false;
209 				if (!fnGetDefaultPrinter(pPrinterName,&iBuffSize))
210                         i = true;
211 
212                 if(i)
213 					rc = GetLastError();
214 				else
215 					rc = ERROR_SUCCESS;
216 
217 				FreeLibrary(hWinSpool);
218 			}
219 			else /* Windows NT 4.0 or earlier */
220 			{
221 				if (GetProfileStringW(L"windows",L"device",L"",pPrinterName,iBufferSize) == iBufferSize-1)
222 				{
223 					rc = ERROR_INSUFFICIENT_BUFFER;
224 				}
225 				else
226 				{
227 					p = pPrinterName;
228 					while (*p != '0' && *p !=L',')
229 						++p;
230 					*p = '0';
231 
232 					rc = ERROR_SUCCESS;
233 				}
234 			}
235 		}
236 	}
237 	while (rc == ERROR_INSUFFICIENT_BUFFER);
238 
239 	return pPrinterName;
240 }
241 
242 /*!
243     This function obtains a DC for the default printer
244     The caller needs to call DeleteDC when dc is no longer needed.
245 */
UT_GetDefaultPrinterDC()246 HDC  UT_GetDefaultPrinterDC()
247 {
248 	wchar_t * pPrinterName  = UT_GetDefaultPrinterName();
249 
250 	if(!pPrinterName || !*pPrinterName)
251 		return NULL;
252 
253 	//	HANDLE hPrinter;
254 	//	if(!OpenPrinter(pPrinterName, &hPrinter, NULL))
255 	//		return NULL;
256 
257 	const wchar_t * pDriver = UT_IsWinNT() ? L"WINSPOOL" : NULL;
258 	HDC hdc = CreateDCW(pDriver, pPrinterName, NULL, NULL);
259 	g_free(pPrinterName);
260 	return hdc;
261 }
262 
263 
264 
UT_RegisterClassEx(UINT style,WNDPROC wndproc,HINSTANCE hInstance,HICON hIcon,HCURSOR hCursor,HBRUSH hbrBackground,HICON hIconSm,const wchar_t * menu,const wchar_t * name)265 ATOM UT_RegisterClassEx(UINT style, WNDPROC wndproc, HINSTANCE hInstance,
266  						HICON hIcon, HCURSOR hCursor, HBRUSH hbrBackground, HICON hIconSm,
267 						const wchar_t * menu, const wchar_t * name)
268 
269 {
270     ATOM atom;
271 	WNDCLASSEXW  wndclass;
272 	memset(&wndclass, 0, sizeof(wndclass));
273 	wndclass.cbSize        = sizeof(wndclass);
274 	wndclass.style         = style;
275 	wndclass.lpfnWndProc   = wndproc;
276 	wndclass.cbClsExtra    = 0;
277 	wndclass.cbWndExtra    = 0;
278 	wndclass.hInstance     = hInstance;
279 	wndclass.hIcon         = hIcon;
280 	wndclass.hCursor       = hCursor;
281 	wndclass.hbrBackground = hbrBackground;
282 	wndclass.lpszMenuName  = menu;
283 	wndclass.lpszClassName = name;
284 	wndclass.hIconSm       = hIconSm;
285 
286 	atom = RegisterClassExW (&wndclass);
287 	UT_ASSERT(atom);
288 	return atom;
289 }
290 
291 
UT_DefWindowProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)292 LRESULT UT_DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam,LPARAM lParam)
293 {
294 	return DefWindowProcW(hWnd, Msg, wParam, lParam);
295 }
296 
297 
UT_SetWindowText(HWND hWnd,const wchar_t * lpString)298 BOOL UT_SetWindowText(HWND hWnd, const wchar_t * lpString)
299 {
300 	return SetWindowTextW(hWnd, lpString);
301 }
302 
303 
304 
UT_GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax)305 BOOL UT_GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
306 {
307 	return GetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
308 }
309 
UT_DispatchMessage(const MSG * lpmsg)310 LRESULT UT_DispatchMessage(const MSG *lpmsg)
311 {
312 	return DispatchMessageW(lpmsg);
313 }
314 
UT_CreateWindowEx(DWORD dwExStyle,const wchar_t * pszClassName,const wchar_t * pszWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam)315 HWND UT_CreateWindowEx(DWORD dwExStyle, const wchar_t * pszClassName, const wchar_t * pszWindowName, DWORD dwStyle,
316  					   int x, int y, int nWidth, int nHeight,
317 					   HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
318 
319  {
320 	HWND hwnd =  CreateWindowExW(dwExStyle, pszClassName, pszWindowName,
321 		dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
322 
323 	UT_ASSERT(hwnd);
324 	return hwnd;
325  }
326