]> git.saurik.com Git - wxWidgets.git/blame - src/os2/utils.cpp
compilation fix
[wxWidgets.git] / src / os2 / utils.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: utils.cpp
3// Purpose: Various utilities
45fcbf3b 4// Author: David Webster
0e320a79 5// Modified by:
45fcbf3b 6// Created: 09/17/99
0e320a79 7// RCS-ID: $Id$
45fcbf3b
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows license
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
45fcbf3b
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/setup.h"
17 #include "wx/utils.h"
18 #include "wx/app.h"
19 #include "wx/cursor.h"
20#endif //WX_PRECOMP
21
22#include "wx/os2/private.h"
23#include "wx/timer.h"
24#include "wx/intl.h"
25
0e320a79 26#include <ctype.h>
45fcbf3b
DW
27#include <direct.h>
28
29#include "wx/log.h"
30
31#include <io.h>
0e320a79
DW
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
45fcbf3b 36#include <errno.h>
0e320a79
DW
37#include <stdarg.h>
38
d90895ac 39#define INCL_DOS
86de7616 40#define INCL_PM
d90895ac 41#define INCL_GPI
86de7616 42#include <os2.h>
45fcbf3b 43#include<netdb.h>
d90895ac 44#define PURE_32
7cdc2f1e
DW
45#include <upm.h>
46#include <netcons.h>
47#include <netbios.h>
45fcbf3b 48
86de7616
DW
49static const wxChar WX_SECTION[] = _T("wxWindows");
50static const wxChar eHOSTNAME[] = _T("HostName");
51static const wxChar eUSERID[] = _T("UserId");
52static const wxChar eUSERNAME[] = _T("UserName");
45fcbf3b
DW
53
54// For the following functions we SHOULD fill in support
55// for Windows-NT (which I don't know) as I assume it begin
56// a POSIX Unix (so claims MS) that it has some special
57// functions beyond those provided by WinSock
58
0e320a79 59// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
10e5b930
DW
60bool wxGetHostName(
61 wxChar* zBuf
62, int nMaxSize
63)
0e320a79 64{
d90895ac 65#if wxUSE_NET_API
10e5b930
DW
66 char zServer[256];
67 char zComputer[256];
004fd0c8 68 unsigned short nLevel = 0;
10e5b930 69 unsigned char* zBuffer;
004fd0c8
DW
70 unsigned short nBuffer;
71 unsigned short* pnTotalAvail;
10e5b930 72
e6ebb514
DW
73 NetBiosGetInfo( (const unsigned char*)zServer
74 ,(const unsigned char*)zComputer
004fd0c8 75 ,nLevel
e6ebb514 76 ,zBuffer
004fd0c8
DW
77 ,nBuffer
78 ,pnTotalAvail
e6ebb514 79 );
10e5b930 80 strcpy(zBuf, zServer);
45fcbf3b 81#else
10e5b930
DW
82 wxChar* zSysname;
83 const wxChar* zDefaultHost = _T("noname");
45fcbf3b 84
10e5b930
DW
85 if ((zSysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL)
86 {
87 ULONG n = ::PrfQueryProfileString( HINI_PROFILE
88 ,(PSZ)WX_SECTION
89 ,(PSZ)eHOSTNAME
90 ,(PSZ)zDefaultHost
91 ,(void*)zBuf
92 ,(ULONG)nMaxSize - 1
93 );
94 }
95 else
96 wxStrncpy(zBuf, zSysname, nMaxSize - 1);
97 zBuf[nMaxSize] = _T('\0');
45fcbf3b 98#endif
10e5b930 99 return *zBuf ? TRUE : FALSE;
0e320a79
DW
100}
101
102// Get user ID e.g. jacs
10e5b930
DW
103bool wxGetUserId(
104 wxChar* zBuf
105, int nMaxSize
106)
0e320a79 107{
10e5b930 108 return(U32ELOCL((unsigned char*)zBuf, (unsigned long *)&nMaxSize));
0e320a79
DW
109}
110
10e5b930
DW
111bool wxGetUserName(
112 wxChar* zBuf
113, int nMaxSize
114)
0e320a79 115{
45fcbf3b 116#ifdef USE_NET_API
10e5b930
DW
117 wxGetUserId( zBuf
118 ,nMaxSize
119 );
45fcbf3b 120#else
10e5b930 121 wxStrncpy(zBuf, _T("Unknown User"), nMaxSize);
45fcbf3b 122#endif
10e5b930 123 return TRUE;
0e320a79
DW
124}
125
10e5b930
DW
126int wxKill(
127 long lPid
128, int nSig
129)
0e320a79 130{
10e5b930 131 return((int)::DosKillProcess(0, (PID)lPid));
0e320a79
DW
132}
133
134//
135// Execute a program in an Interactive Shell
136//
10e5b930
DW
137bool wxShell(
138 const wxString& rCommand
139)
0e320a79 140{
10e5b930 141 wxChar* zShell;
45fcbf3b 142
10e5b930
DW
143 if ((zShell = wxGetenv(_T("COMSPEC"))) == NULL)
144 zShell = _T("\\CMD.EXE");
45fcbf3b 145
10e5b930
DW
146 wxChar zTmp[255];
147
148 if (rCommand != "")
149 wxSprintf( zTmp
150 ,"%s /c %s"
151 ,zShell
152 ,WXSTRINGCAST rCommand
153 );
154 else
155 wxStrcpy(zTmp, zShell);
156
157 return (wxExecute((wxChar*)zTmp, FALSE) != 0);
0e320a79
DW
158}
159
160// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
10e5b930
DW
161long wxGetFreeMemory(
162 void* pMemptr
163)
0e320a79 164{
78d50441
DW
165 ULONG lSize;
166 ULONG lMemFlags;
167 APIRET rc;
168
169 lMemFlags = PAG_FREE;
10e5b930 170 rc = ::DosQueryMem(pMemptr, &lSize, &lMemFlags);
78d50441
DW
171 if (rc != 0)
172 return -1L;
173 return (long)lSize;
45fcbf3b
DW
174}
175
176// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
177static bool inTimer = FALSE;
178
179class wxSleepTimer: public wxTimer
180{
10e5b930
DW
181public:
182 inline void Notify()
183 {
184 inTimer = FALSE;
185 Stop();
186 }
45fcbf3b
DW
187};
188
10e5b930 189static wxTimer* wxTheSleepTimer = NULL;
45fcbf3b 190
10e5b930
DW
191void wxUsleep(
192 unsigned long ulMilliseconds
193)
45fcbf3b 194{
10e5b930 195 ::DosSleep(ulMilliseconds);
0e320a79
DW
196}
197
10e5b930
DW
198void wxSleep(
199 int nSecs
200)
0e320a79 201{
10e5b930 202 ::DosSleep(1000 * nSecs);
0e320a79
DW
203}
204
205// Consume all events until no more left
206void wxFlushEvents()
207{
45fcbf3b 208// wxYield();
0e320a79
DW
209}
210
45fcbf3b 211// Output a debug mess., in a system dependent fashion.
10e5b930
DW
212void wxDebugMsg(
213 const wxChar* zFmt ...
214)
215{
216 va_list vAp;
217 static wxChar zBuffer[512];
218
219 if (!wxTheApp->GetWantDebugOutput())
220 return ;
221 va_start(vAp, zFmt);
222 sprintf(zBuffer, zFmt, vAp) ;
223 va_end(vAp);
0e320a79
DW
224}
225
226// Non-fatal error: pop up message box and (possibly) continue
10e5b930
DW
227void wxError(
228 const wxString& rMsg
229, const wxString& rTitle
230)
231{
232 wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST rMsg);
233 if (::WinMessageBox( HWND_DESKTOP
234 ,NULL
235 ,(PSZ)wxBuffer
236 ,(PSZ)WXSTRINGCAST rTitle
237 ,0
238 ,MB_ICONEXCLAMATION | MB_YESNO
239 ) == MBID_YES)
0e320a79
DW
240 wxExit();
241}
242
243// Fatal error: pop up message box and abort
10e5b930
DW
244void wxFatalError(
245 const wxString& rMsg
246, const wxString& rTitle
247)
248{
249 unsigned long ulRc;
250
251 ulRc = ::WinMessageBox( HWND_DESKTOP
252 ,NULL
253 ,WXSTRINGCAST rMsg
254 ,WXSTRINGCAST rTitle
255 ,0
256 ,MB_NOICON | MB_OK
257 );
258 DosExit(EXIT_PROCESS, ulRc);
0e320a79
DW
259}
260
261// Emit a beeeeeep
262void wxBell()
263{
45fcbf3b 264 DosBeep(1000,1000); // 1kHz during 1 sec.
0e320a79
DW
265}
266
45fcbf3b
DW
267// Chris Breeze 27/5/98: revised WIN32 code to
268// detect WindowsNT correctly
10e5b930
DW
269int wxGetOsVersion(
270 int* pMajorVsn
271, int* pMinorVsn
272)
273{
274 ULONG ulSysInfo[QSV_MAX] = {0};
275
276 if (::DosQuerySysInfo( 1L
277 ,QSV_MAX
278 ,(PVOID)ulSysInfo
279 ,sizeof(ULONG) * QSV_MAX
280 ))
281 {
282 *pMajorVsn = ulSysInfo[QSV_VERSION_MAJOR];
283 *pMinorVsn = ulSysInfo[QSV_VERSION_MINOR];
284 return wxWINDOWS_OS2;
285 }
286 return wxWINDOWS; // error if we get here, return generic value
0e320a79
DW
287}
288
289// Reading and writing resources (eg WIN.INI, .Xdefaults)
290#if wxUSE_RESOURCES
10e5b930
DW
291bool wxWriteResource(
292 const wxString& rSection
293, const wxString& rEntry
294, const wxString& rValue
295, const wxString& rFile
296)
0e320a79 297{
78d50441
DW
298 HAB hab;
299 HINI hIni;
300
10e5b930 301 if (rFile != "")
78d50441 302 {
10e5b930 303 hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile);
78d50441
DW
304 if (hIni != 0L)
305 {
306 return (::PrfWriteProfileString( hIni
10e5b930
DW
307 ,(PSZ)WXSTRINGCAST rSection
308 ,(PSZ)WXSTRINGCAST rEntry
309 ,(PSZ)WXSTRINGCAST rValue
78d50441
DW
310 ));
311 }
312 }
313 else
314 return (::PrfWriteProfileString( HINI_PROFILE
10e5b930
DW
315 ,(PSZ)WXSTRINGCAST rSection
316 ,(PSZ)WXSTRINGCAST rEntry
317 ,(PSZ)WXSTRINGCAST rValue
78d50441 318 ));
d90895ac 319 return FALSE;
0e320a79
DW
320}
321
10e5b930
DW
322bool wxWriteResource(
323 const wxString& rSection
324, const wxString& rEntry
325, float fValue
326, const wxString& rFile
327)
328{
329 wxChar zBuf[50];
330
331 wxSprintf(zBuf, "%.4f", fValue);
332 return wxWriteResource( rSection
333 ,rEntry
334 ,zBuf
335 ,rFile
336 );
0e320a79
DW
337}
338
1be7f92a
DW
339bool wxWriteResource(
340 const wxString& rSection
341, const wxString& rEntry
342, long lValue
343, const wxString& rFile
344)
0e320a79 345{
1be7f92a
DW
346 wxChar zBuf[50];
347
348 wxSprintf(zBuf, "%ld", lValue);
349 return wxWriteResource( rSection
350 ,rEntry
351 ,zBuf
352 ,rFile
353 );
0e320a79
DW
354}
355
1be7f92a
DW
356bool wxWriteResource(
357 const wxString& rSection
358, const wxString& rEntry
359, int lValue
360, const wxString& rFile
361)
0e320a79 362{
1be7f92a
DW
363 wxChar zBuf[50];
364
365 wxSprintf(zBuf, "%d", lValue);
366 return wxWriteResource( rSection
367 ,rEntry
368 ,zBuf
369 ,rFile
370 );
0e320a79
DW
371}
372
1be7f92a
DW
373bool wxGetResource(
374 const wxString& rSection
375, const wxString& rEntry
376, wxChar** ppValue
377, const wxString& rFile
378)
0e320a79 379{
78d50441
DW
380 HAB hab;
381 HINI hIni;
1be7f92a 382 static const wxChar zDefunkt[] = _T("$$default");
78d50441 383
1be7f92a 384 if (rFile != "")
78d50441 385 {
1be7f92a 386 hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile);
78d50441
DW
387 if (hIni != 0L)
388 {
389 ULONG n = ::PrfQueryProfileString( hIni
1be7f92a
DW
390 ,(PSZ)WXSTRINGCAST rSection
391 ,(PSZ)WXSTRINGCAST rEntry
392 ,(PSZ)zDefunkt
78d50441
DW
393 ,(void*)wxBuffer
394 ,1000
395 );
1be7f92a 396 if (n == 0L || wxStrcmp(wxBuffer, zDefunkt) == 0)
78d50441
DW
397 return FALSE;
398 }
399 else
400 return FALSE;
401 }
402 else
403 {
404 ULONG n = ::PrfQueryProfileString( HINI_PROFILE
1be7f92a
DW
405 ,(PSZ)WXSTRINGCAST rSection
406 ,(PSZ)WXSTRINGCAST rEntry
407 ,(PSZ)zDefunkt
78d50441
DW
408 ,(void*)wxBuffer
409 ,1000
410 );
1be7f92a 411 if (n == 0L || wxStrcmp(wxBuffer, zDefunkt) == 0)
78d50441
DW
412 return FALSE;
413 }
1be7f92a
DW
414 if (*ppValue)
415 delete[] (*ppValue);
416 *ppValue = copystring(wxBuffer);
78d50441 417 return TRUE;
d90895ac 418}
0e320a79 419
1be7f92a
DW
420bool wxGetResource(
421 const wxString& rSection
422, const wxString& rEntry
423, float* pValue
424, const wxString& rFile
425)
0e320a79 426{
1be7f92a
DW
427 wxChar* zStr = NULL;
428 bool bSucc = wxGetResource( rSection
429 ,rEntry
430 ,(wxChar **)&zStr
431 ,rFile
432 );
433
434 if (bSucc)
435 {
436 *pValue = (float)wxStrtod(zStr, NULL);
437 delete[] zStr;
438 return TRUE;
439 }
440 else return FALSE;
0e320a79
DW
441}
442
1be7f92a
DW
443bool wxGetResource(
444 const wxString& rSection
445, const wxString& rEntry
446, long* pValue
447, const wxString& rFile
448)
0e320a79 449{
1be7f92a
DW
450 wxChar* zStr = NULL;
451 bool bSucc = wxGetResource( rSection
452 ,rEntry
453 ,(wxChar **)&zStr
454 ,rFile
455 );
456
457 if (bSucc)
458 {
459 *pValue = wxStrtol(zStr, NULL, 10);
460 delete[] zStr;
461 return TRUE;
462 }
463 else return FALSE;
0e320a79
DW
464}
465
1be7f92a
DW
466bool wxGetResource(
467 const wxString& rSection
468, const wxString& rEntry
469, int* pValue
470, const wxString& rFile
471)
0e320a79 472{
1be7f92a
DW
473 wxChar* zStr = NULL;
474 bool bSucc = wxGetResource( rSection
475 ,rEntry
476 ,(wxChar **)&zStr
477 ,rFile
478 );
479
480 if (bSucc)
481 {
482 *pValue = (int)wxStrtol(zStr, NULL, 10);
483 delete[] zStr;
484 return TRUE;
485 }
486 else return FALSE;
0e320a79
DW
487}
488#endif // wxUSE_RESOURCES
489
45fcbf3b
DW
490// ---------------------------------------------------------------------------
491// helper functions for showing a "busy" cursor
492// ---------------------------------------------------------------------------
493
494HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
495HCURSOR gs_wxBusyCursorOld = 0; // old cursor
496static int gs_wxBusyCursorCount = 0;
0e320a79
DW
497
498// Set the cursor to the busy cursor for all windows
1be7f92a
DW
499void wxBeginBusyCursor(
500 wxCursor* pCursor
501)
0e320a79 502{
45fcbf3b
DW
503 if ( gs_wxBusyCursorCount++ == 0 )
504 {
1be7f92a 505 gs_wxBusyCursor = (HCURSOR)pCursor->GetHCURSOR();
45fcbf3b
DW
506 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor);
507 }
508 //else: nothing to do, already set
0e320a79
DW
509}
510
511// Restore cursor to normal
512void wxEndBusyCursor()
513{
1be7f92a
DW
514 wxCHECK_RET( gs_wxBusyCursorCount > 0
515 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
516 );
45fcbf3b 517
1be7f92a 518 if (--gs_wxBusyCursorCount == 0)
45fcbf3b
DW
519 {
520 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld);
521 gs_wxBusyCursorOld = 0;
522 }
0e320a79
DW
523}
524
525// TRUE if we're between the above two calls
526bool wxIsBusy()
527{
1be7f92a 528 return (gs_wxBusyCursorCount > 0);
45fcbf3b
DW
529}
530
531// ---------------------------------------------------------------------------
1be7f92a
DW
532const wxChar* wxGetHomeDir(
533 wxString* pStr
534)
45fcbf3b 535{
1be7f92a 536 wxString& rStrDir = *pStr;
0e320a79 537
1be7f92a
DW
538 // OS/2 has no idea about home,
539 // so use the working directory instead?
45fcbf3b 540
1be7f92a 541 // 256 was taken from os2def.h
45fcbf3b
DW
542#ifndef MAX_PATH
543# define MAX_PATH 256
544#endif
545
1be7f92a
DW
546 char zDirName[256];
547 ULONG ulDirLen;
45fcbf3b 548
1be7f92a
DW
549 ::DosQueryCurrentDir(0, zDirName, &ulDirLen);
550 rStrDir = zDirName;
551 return rStrDir.c_str();
45fcbf3b
DW
552}
553
10e5b930 554// Hack for OS/2
1be7f92a
DW
555wxChar* wxGetUserHome (
556 const wxString& rUser
557)
558{
559 wxChar* zHome;
560 wxString sUser1(rUser);
561
562 if (sUser1 != _T(""))
45fcbf3b 563 {
1be7f92a
DW
564 wxChar zTmp[64];
565
566 if (wxGetUserId( zTmp
567 ,sizeof(zTmp)/sizeof(char)
568 ))
569 {
570 // Guests belong in the temp dir
571 if (wxStricmp(zTmp, _T("annonymous")) == 0)
572 {
573 if ((zHome = wxGetenv(_T("TMP"))) != NULL ||
574 (zHome = wxGetenv(_T("TMPDIR"))) != NULL ||
575 (zHome = wxGetenv(_T("TEMP"))) != NULL)
576 return *zHome ? zHome : (wxChar*)_T("\\");
577 }
578 if (wxStricmp(zTmp, WXSTRINGCAST sUser1) == 0)
579 sUser1 = _T("");
580 }
45fcbf3b 581 }
1be7f92a
DW
582 if (sUser1 == _T(""))
583 if ((zHome = wxGetenv(_T("HOME"))) != NULL)
584 {
585 wxStrcpy(wxBuffer, zHome);
586 Unix2DosFilename(wxBuffer);
587 return wxBuffer;
588 }
589 return NULL; // No home known!
0e320a79
DW
590}
591
592// Check whether this window wants to process messages, e.g. Stop button
593// in long calculations.
1be7f92a
DW
594bool wxCheckForInterrupt(
595 wxWindow* pWnd
596)
0e320a79 597{
1be7f92a
DW
598 if(pWnd)
599 {
600 QMSG vMsg;
601 HAB hab;
602 HWND hwndFilter;
603 HWND hwndWin= (HWND) pWnd->GetHWND();
45fcbf3b 604
1be7f92a
DW
605 while(::WinPeekMsg(hab, &vMsg, hwndFilter, 0, 0, PM_REMOVE))
606 {
607 ::WinDispatchMsg(hab, &vMsg);
608 }
609 return TRUE;//*** temporary?
610 }
611 else
45fcbf3b 612 {
1be7f92a
DW
613 wxFAIL_MSG(_T("pWnd==NULL !!!"));
614 return FALSE;//*** temporary?
45fcbf3b 615 }
45fcbf3b
DW
616}
617
1be7f92a
DW
618void wxGetMousePosition(
619 int* pX
620, int* pY
621)
0e320a79 622{
1be7f92a
DW
623 POINTL vPt;
624
625 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
626 *pX = vPt.x;
627 *pY = vPt.y;
0e320a79
DW
628};
629
630// Return TRUE if we have a colour display
631bool wxColourDisplay()
632{
1be7f92a
DW
633 HPS hpsScreen;
634 HDC hdcScreen;
635 LONG lColors;
636
637 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
638 hdcScreen = ::GpiQueryDevice(hpsScreen);
639 ::DevQueryCaps(hdcScreen, CAPS_COLORS, 1L, &lColors);
640 return(lColors > 1L);
0e320a79
DW
641}
642
643// Returns depth of screen
644int wxDisplayDepth()
645{
1be7f92a
DW
646 HPS hpsScreen;
647 HDC hdcScreen;
648 LONG lPlanes;
649 LONG lBitsPerPixel;
650 LONG nDepth;
651
652 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
653 hdcScreen = ::GpiQueryDevice(hpsScreen);
654 ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes);
655 ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel);
656
657 nDepth = (int)(lPlanes * lBitsPerPixel);
658 DevCloseDC(hdcScreen);
d90895ac 659 return (nDepth);
0e320a79
DW
660}
661
662// Get size of display
1be7f92a
DW
663void wxDisplaySize(
664 int* pWidth
665, int* pHeight
666)
0e320a79 667{
1be7f92a
DW
668 HPS hpsScreen;
669 HDC hdcScreen;
45fcbf3b 670
1be7f92a
DW
671 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
672 hdcScreen = ::GpiQueryDevice(hpsScreen);
673 ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, (PLONG)pWidth);
674 ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, (PLONG)pHeight);
675 DevCloseDC(hdcScreen);
45fcbf3b
DW
676}
677
1be7f92a
DW
678bool wxDirExists(
679 const wxString& rDir
680)
45fcbf3b 681{
1be7f92a 682 return (::DosSetCurrentDir(WXSTRINGCAST rDir));
45fcbf3b
DW
683}
684
685// ---------------------------------------------------------------------------
686// window information functions
687// ---------------------------------------------------------------------------
688
1be7f92a
DW
689wxString WXDLLEXPORT wxGetWindowText(
690 WXHWND hWnd
691)
45fcbf3b 692{
1be7f92a
DW
693 wxString vStr;
694 long lLen = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
695
696 ::WinQueryWindowText((HWND)hWnd, lLen, vStr.GetWriteBuf((int)lLen));
697 vStr.UngetWriteBuf();
45fcbf3b 698
1be7f92a 699 return vStr;
45fcbf3b
DW
700}
701
1be7f92a
DW
702wxString WXDLLEXPORT wxGetWindowClass(
703 WXHWND hWnd
704)
45fcbf3b 705{
1be7f92a
DW
706 wxString vStr;
707 int nLen = 256; // some starting value
45fcbf3b
DW
708
709 for ( ;; )
710 {
1be7f92a 711 int nCount = ::WinQueryClassName((HWND)hWnd, nLen, vStr.GetWriteBuf(nLen));
45fcbf3b 712
1be7f92a
DW
713 vStr.UngetWriteBuf();
714 if (nCount == nLen )
45fcbf3b
DW
715 {
716 // the class name might have been truncated, retry with larger
717 // buffer
1be7f92a 718 nLen *= 2;
45fcbf3b
DW
719 }
720 else
721 {
722 break;
723 }
724 }
1be7f92a 725 return vStr;
45fcbf3b
DW
726}
727
1be7f92a
DW
728WXWORD WXDLLEXPORT wxGetWindowId(
729 WXHWND hWnd
730)
45fcbf3b
DW
731{
732 return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
0e320a79
DW
733}
734