1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/utilsgui.cpp 
   3 // Purpose:     Various utility functions only available in GUI 
   4 // Author:      Vadim Zeitlin 
   6 // Created:     21.06.2003 (extracted from msw/utils.cpp) 
   8 // Copyright:   (c) Julian Smart 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // for compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  28     #include "wx/cursor.h" 
  29     #include "wx/window.h" 
  33 #include "wx/dynlib.h" 
  35 #include "wx/msw/private.h"     // includes <windows.h> 
  37 // ============================================================================ 
  39 // ============================================================================ 
  41 // ---------------------------------------------------------------------------- 
  42 // functions to work with .INI files 
  43 // ---------------------------------------------------------------------------- 
  45 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
  47 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
) 
  49   if (file 
!= wxEmptyString
) 
  50 // Don't know what the correct cast should be, but it doesn't 
  51 // compile in BC++/16-bit without this cast. 
  52 #if !defined(__WIN32__) 
  53     return (WritePrivateProfileString((const char*) section
, (const char*) entry
, (const char*) value
, (const char*) file
) != 0); 
  55     return (WritePrivateProfileString((LPCTSTR
)WXSTRINGCAST section
, (LPCTSTR
)WXSTRINGCAST entry
, (LPCTSTR
)value
, (LPCTSTR
)WXSTRINGCAST file
) != 0); 
  58     return (WriteProfileString((LPCTSTR
)WXSTRINGCAST section
, (LPCTSTR
)WXSTRINGCAST entry
, (LPCTSTR
)WXSTRINGCAST value
) != 0); 
  61 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
) 
  64     buf
.Printf(wxT("%.4f"), value
); 
  66     return wxWriteResource(section
, entry
, buf
, file
); 
  69 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
) 
  72     buf
.Printf(wxT("%ld"), value
); 
  74     return wxWriteResource(section
, entry
, buf
, file
); 
  77 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
) 
  80     buf
.Printf(wxT("%d"), value
); 
  82     return wxWriteResource(section
, entry
, buf
, file
); 
  85 bool wxGetResource(const wxString
& section
, const wxString
& entry
, wxChar 
**value
, const wxString
& file
) 
  87     static const wxChar defunkt
[] = wxT("$$default"); 
  90     if (file 
!= wxEmptyString
) 
  92         int n 
= GetPrivateProfileString(section
, entry
, defunkt
, 
  93                                         buf
, WXSIZEOF(buf
), file
); 
  94         if (n 
== 0 || wxStrcmp(buf
, defunkt
) == 0) 
  99         int n 
= GetProfileString(section
, entry
, defunkt
, buf
, WXSIZEOF(buf
)); 
 100         if (n 
== 0 || wxStrcmp(buf
, defunkt
) == 0) 
 103     if (*value
) delete[] (*value
); 
 104     *value 
= wxStrcpy(new wxChar
[wxStrlen(buf
) + 1], buf
); 
 108 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
) 
 111     bool succ 
= wxGetResource(section
, entry
, (wxChar 
**)&s
, file
); 
 114         *value 
= (float)wxStrtod(s
, NULL
); 
 121 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
) 
 124     bool succ 
= wxGetResource(section
, entry
, (wxChar 
**)&s
, file
); 
 127         *value 
= wxStrtol(s
, NULL
, 10); 
 134 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
) 
 137     bool succ 
= wxGetResource(section
, entry
, (wxChar 
**)&s
, file
); 
 140         *value 
= (int)wxStrtol(s
, NULL
, 10); 
 146 #endif // wxUSE_RESOURCES 
 148 // --------------------------------------------------------------------------- 
 149 // helper functions for showing a "busy" cursor 
 150 // --------------------------------------------------------------------------- 
 152 static HCURSOR gs_wxBusyCursor 
= 0;     // new, busy cursor 
 153 static HCURSOR gs_wxBusyCursorOld 
= 0;  // old cursor 
 154 static int gs_wxBusyCursorCount 
= 0; 
 156 extern HCURSOR 
wxGetCurrentBusyCursor() 
 158     return gs_wxBusyCursor
; 
 161 // Set the cursor to the busy cursor for all windows 
 162 void wxBeginBusyCursor(const wxCursor 
*cursor
) 
 164     if ( gs_wxBusyCursorCount
++ == 0 ) 
 166         gs_wxBusyCursor 
= (HCURSOR
)cursor
->GetHCURSOR(); 
 167 #ifndef __WXMICROWIN__ 
 168         gs_wxBusyCursorOld 
= ::SetCursor(gs_wxBusyCursor
); 
 171     //else: nothing to do, already set 
 174 // Restore cursor to normal 
 175 void wxEndBusyCursor() 
 177     wxCHECK_RET( gs_wxBusyCursorCount 
> 0, 
 178                  wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") ); 
 180     if ( --gs_wxBusyCursorCount 
== 0 ) 
 182 #ifndef __WXMICROWIN__ 
 183         ::SetCursor(gs_wxBusyCursorOld
); 
 185         gs_wxBusyCursorOld 
= 0; 
 189 // true if we're between the above two calls 
 192   return gs_wxBusyCursorCount 
> 0; 
 195 // Check whether this window wants to process messages, e.g. Stop button 
 196 // in long calculations. 
 197 bool wxCheckForInterrupt(wxWindow 
*wnd
) 
 199     wxCHECK( wnd
, false ); 
 202     while ( ::PeekMessage(&msg
, GetHwndOf(wnd
), 0, 0, PM_REMOVE
) ) 
 204         ::TranslateMessage(&msg
); 
 205         ::DispatchMessage(&msg
); 
 211 // MSW only: get user-defined resource from the .res file. 
 212 // Returns NULL or newly-allocated memory, so use delete[] to clean up. 
 214 #ifndef __WXMICROWIN__ 
 215 wxChar 
*wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
) 
 217     HRSRC hResource 
= ::FindResource(wxGetInstance(), resourceName
, resourceType
); 
 218     if ( hResource 
== 0 ) 
 221     HGLOBAL hData 
= ::LoadResource(wxGetInstance(), hResource
); 
 225     wxChar 
*theText 
= (wxChar 
*)::LockResource(hData
); 
 229     // Not all compilers put a zero at the end of the resource (e.g. BC++ doesn't). 
 230     // so we need to find the length of the resource. 
 231     int len 
= ::SizeofResource(wxGetInstance(), hResource
); 
 232     wxChar  
*s 
= new wxChar
[len
+1]; 
 233     wxStrncpy(s
,theText
,len
); 
 236     // wxChar *s = copystring(theText); 
 240     UnlockResource(hData
); 
 244     //  GlobalFree(hData); 
 248 #endif // __WXMICROWIN__ 
 250 // ---------------------------------------------------------------------------- 
 252 // ---------------------------------------------------------------------------- 
 254 // See also the wxGetMousePosition in window.cpp 
 255 // Deprecated: use wxPoint wxGetMousePosition() instead 
 256 void wxGetMousePosition( int* x
, int* y 
) 
 259     GetCursorPos( & pt 
); 
 264 // Return true if we have a colour display 
 265 bool wxColourDisplay() 
 267 #ifdef __WXMICROWIN__ 
 271     // this function is called from wxDC ctor so it is called a *lot* of times 
 272     // hence we optimize it a bit but doing the check only once 
 274     // this should be MT safe as only the GUI thread (holding the GUI mutex) 
 276     static int s_isColour 
= -1; 
 278     if ( s_isColour 
== -1 ) 
 281         int noCols 
= ::GetDeviceCaps(dc
, NUMCOLORS
); 
 283         s_isColour 
= (noCols 
== -1) || (noCols 
> 2); 
 286     return s_isColour 
!= 0; 
 290 // Returns depth of screen 
 294     return GetDeviceCaps(dc
, PLANES
) * GetDeviceCaps(dc
, BITSPIXEL
); 
 297 // Get size of display 
 298 void wxDisplaySize(int *width
, int *height
) 
 300 #ifdef __WXMICROWIN__ 
 302     HWND hWnd 
= GetDesktopWindow(); 
 303     ::GetWindowRect(hWnd
, & rect
); 
 306         *width 
= rect
.right 
- rect
.left
; 
 308         *height 
= rect
.bottom 
- rect
.top
; 
 309 #else // !__WXMICROWIN__ 
 313         *width 
= ::GetDeviceCaps(dc
, HORZRES
); 
 315         *height 
= ::GetDeviceCaps(dc
, VERTRES
); 
 316 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 319 void wxDisplaySizeMM(int *width
, int *height
) 
 321 #ifdef __WXMICROWIN__ 
 331         *width 
= ::GetDeviceCaps(dc
, HORZSIZE
); 
 333         *height 
= ::GetDeviceCaps(dc
, VERTSIZE
); 
 337 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 339 #if defined(__WXMICROWIN__) 
 341     wxDisplaySize(width
, height
); 
 343     // Determine the desktop dimensions minus the taskbar and any other 
 344     // special decorations... 
 347     SystemParametersInfo(SPI_GETWORKAREA
, 0, &r
, 0); 
 350     if (width
)  *width 
= r
.right 
- r
.left
; 
 351     if (height
) *height 
= r
.bottom 
- r
.top
; 
 355 // --------------------------------------------------------------------------- 
 356 // window information functions 
 357 // --------------------------------------------------------------------------- 
 359 wxString WXDLLEXPORT 
wxGetWindowText(WXHWND hWnd
) 
 365         int len 
= GetWindowTextLength((HWND
)hWnd
) + 1; 
 366         ::GetWindowText((HWND
)hWnd
, wxStringBuffer(str
, len
), len
); 
 372 wxString WXDLLEXPORT 
wxGetWindowClass(WXHWND hWnd
) 
 377 #ifndef __WXMICROWIN__ 
 380         int len 
= 256; // some starting value 
 384             int count 
= ::GetClassName((HWND
)hWnd
, wxStringBuffer(str
, len
), len
); 
 388                 // the class name might have been truncated, retry with larger 
 398 #endif // !__WXMICROWIN__ 
 403 WXWORD WXDLLEXPORT 
wxGetWindowId(WXHWND hWnd
) 
 405     return (WXWORD
)GetWindowLong((HWND
)hWnd
, GWL_ID
); 
 408 // ---------------------------------------------------------------------------- 
 410 // ---------------------------------------------------------------------------- 
 412 extern void PixelToHIMETRIC(LONG 
*x
, LONG 
*y
) 
 416     int iWidthMM 
= GetDeviceCaps(hdcRef
, HORZSIZE
), 
 417         iHeightMM 
= GetDeviceCaps(hdcRef
, VERTSIZE
), 
 418         iWidthPels 
= GetDeviceCaps(hdcRef
, HORZRES
), 
 419         iHeightPels 
= GetDeviceCaps(hdcRef
, VERTRES
); 
 421     *x 
*= (iWidthMM 
* 100); 
 423     *y 
*= (iHeightMM 
* 100); 
 427 extern void HIMETRICToPixel(LONG 
*x
, LONG 
*y
) 
 431     int iWidthMM 
= GetDeviceCaps(hdcRef
, HORZSIZE
), 
 432         iHeightMM 
= GetDeviceCaps(hdcRef
, VERTSIZE
), 
 433         iWidthPels 
= GetDeviceCaps(hdcRef
, HORZRES
), 
 434         iHeightPels 
= GetDeviceCaps(hdcRef
, VERTRES
); 
 437     *x 
/= (iWidthMM 
* 100); 
 439     *y 
/= (iHeightMM 
* 100); 
 442 void wxDrawLine(HDC hdc
, int x1
, int y1
, int x2
, int y2
) 
 450     Polyline(hdc
, points
, 2); 
 452     MoveToEx(hdc
, x1
, y1
, NULL
); LineTo((HDC
) hdc
, x2
, y2
); 
 457 // ---------------------------------------------------------------------------- 
 458 // Shell API wrappers 
 459 // ---------------------------------------------------------------------------- 
 461 extern bool wxEnableFileNameAutoComplete(HWND hwnd
) 
 463 #if wxUSE_DYNLIB_CLASS 
 464     typedef HRESULT (WINAPI 
*SHAutoComplete_t
)(HWND
, DWORD
); 
 466     static SHAutoComplete_t s_pfnSHAutoComplete 
= NULL
; 
 467     static bool s_initialized 
= false; 
 469     if ( !s_initialized 
) 
 471         s_initialized 
= true; 
 474         wxDynamicLibrary 
dll(_T("shlwapi.dll")); 
 475         if ( dll
.IsLoaded() ) 
 477             s_pfnSHAutoComplete 
= 
 478                 (SHAutoComplete_t
)dll
.GetSymbol(_T("SHAutoComplete")); 
 479             if ( s_pfnSHAutoComplete 
) 
 481                 // won't be unloaded until the process termination, no big deal 
 487     if ( !s_pfnSHAutoComplete 
) 
 490     HRESULT hr 
= s_pfnSHAutoComplete(hwnd
, 0x10 /* SHACF_FILESYS_ONLY */); 
 493         wxLogApiError(_T("SHAutoComplete"), hr
); 
 501 #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS