1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Various utilities 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  19     #include "wx/cursor.h" 
  22 #include "wx/os2/private.h" 
  49 static const wxChar WX_SECTION
[] = _T("wxWindows"); 
  50 static const wxChar eHOSTNAME
[]  = _T("HostName"); 
  51 static const wxChar eUSERID
[]    = _T("UserId"); 
  52 static const wxChar eUSERNAME
[]  = _T("UserName"); 
  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 
  59 // Get full hostname (eg. DoDo.BSn-Germany.crg.de) 
  68     unsigned long                   ulLevel 
= 0; 
  69     unsigned char*                  zBuffer 
= NULL
; 
  70     unsigned long                   ulBuffer 
= 256; 
  71     unsigned long*                  pulTotalAvail 
= NULL
; 
  73     NetBios32GetInfo( (const unsigned char*)zServer
 
  74                      ,(const unsigned char*)zComputer
 
  80     strcpy(zBuf
, zServer
); 
  83     const wxChar
*                   zDefaultHost 
= _T("noname"); 
  85     if ((zSysname 
= wxGetenv(_T("SYSTEM_NAME"))) == NULL
) 
  87         ULONG n 
= ::PrfQueryProfileString( HINI_PROFILE
 
  96         wxStrncpy(zBuf
, zSysname
, nMaxSize 
- 1); 
  97     zBuf
[nMaxSize
] = _T('\0'); 
  99     return *zBuf 
? TRUE 
: FALSE
; 
 102 // Get user ID e.g. jacs 
 110     // UPM procs return 0 on success 
 111     lrc 
= U32ELOCU((unsigned char*)zBuf
, (unsigned long *)&nType
); 
 112     if (lrc 
== 0) return TRUE
; 
 127     wxStrncpy(zBuf
, _T("Unknown User"), nMaxSize
); 
 135 , wxKillError
*                      peError
 
 138     return((int)::DosKillProcess(0, (PID
)lPid
)); 
 142 // Execute a program in an Interactive Shell 
 145   const wxString
&                   rCommand
 
 148     wxChar
*                         zShell 
= _T("CMD.EXE"); 
 151     STARTDATA                       SData 
= {0}; 
 152     PSZ                             PgmTitle 
= "Command Shell"; 
 156     UCHAR                           achObjBuf
[256] = {0}; //error data if DosStart fails 
 159     SData
.Length   
= sizeof(STARTDATA
); 
 160     SData
.Related  
= SSF_RELATED_INDEPENDENT
; 
 161     SData
.FgBg     
= SSF_FGBG_FORE
; 
 162     SData
.TraceOpt 
= SSF_TRACEOPT_NONE
; 
 163     SData
.PgmTitle 
= PgmTitle
; 
 164     SData
.PgmName  
= zShell
; 
 166     sInputs 
= "/C " + rCommand
; 
 167     SData
.PgmInputs     
= (BYTE
*)sInputs
.c_str(); 
 169     SData
.Environment   
= 0; 
 170     SData
.InheritOpt    
= SSF_INHERTOPT_SHELL
; 
 171     SData
.SessionType   
= SSF_TYPE_WINDOWABLEVIO
; 
 174     SData
.PgmControl    
= SSF_CONTROL_VISIBLE 
| SSF_CONTROL_MAXIMIZE
; 
 177     SData
.InitXSize     
= 200; 
 178     SData
.InitYSize     
= 140; 
 180     SData
.ObjectBuffer  
= (char*)achObjBuf
; 
 181     SData
.ObjectBuffLen 
= (ULONG
)sizeof(achObjBuf
); 
 183     rc 
= ::DosStartSession(&SData
, &ulSessID
, &vPid
); 
 184     if (rc 
== 0 || rc 
== 457) // NO_ERROR or SMG_START_IN_BACKGROUND 
 189         ::DosGetInfoBlocks(&ptib
, &ppib
); 
 191         ::DosWaitChild( DCWA_PROCESS
 
 201 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) 
 202 long wxGetFreeMemory() 
 204     void*                           pMemptr 
= NULL
; 
 209     lMemFlags 
= PAG_FREE
; 
 210     rc 
= ::DosQueryMem(pMemptr
, &lSize
, &lMemFlags
); 
 216 // ---------------------------------------------------------------------------- 
 218 // ---------------------------------------------------------------------------- 
 220 bool wxGetEnv(const wxString
& var
, wxString 
*value
) 
 222     // wxGetenv is defined as getenv() 
 223     wxChar 
*p 
= wxGetenv(var
); 
 235 bool wxSetEnv(const wxString
& variable
, const wxChar 
*value
) 
 237 #if defined(HAVE_SETENV) 
 238     return setenv(variable
.mb_str(), value 
? wxString(value
).mb_str().data() 
 239                                            : NULL
, 1 /* overwrite */) == 0; 
 240 #elif defined(HAVE_PUTENV) 
 241     wxString s 
= variable
; 
 243         s 
<< _T('=') << value
; 
 246     const char *p 
= s
.mb_str(); 
 248     // the string will be free()d by libc 
 249     char *buf 
= (char *)malloc(strlen(p
) + 1); 
 252     return putenv(buf
) == 0; 
 253 #else // no way to set an env var 
 259 // Sleep for nSecs seconds. Attempt a Windows implementation using timers. 
 260 static bool inTimer 
= FALSE
; 
 262 class wxSleepTimer
: public wxTimer
 
 272 static wxTimer
*                     wxTheSleepTimer 
= NULL
; 
 275   unsigned long                     ulMilliseconds
 
 278     ::DosSleep(ulMilliseconds
/1000l); 
 285     ::DosSleep(1000 * nSecs
); 
 288 // Consume all events until no more left 
 294 // Output a debug mess., in a system dependent fashion. 
 296   const wxChar
*                     zFmt 
... 
 300     static wxChar                   zBuffer
[512]; 
 302     if (!wxTheApp
->GetWantDebugOutput()) 
 305     sprintf(zBuffer
, zFmt
, vAp
) ; 
 309 // Non-fatal error: pop up message box and (possibly) continue 
 312 , const wxString
&                   rTitle
 
 315     wxBuffer 
= new wxChar
[256]; 
 316     wxSprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST rMsg
); 
 317     if (::WinMessageBox( HWND_DESKTOP
 
 320                         ,(PSZ
)WXSTRINGCAST rTitle
 
 322                         ,MB_ICONEXCLAMATION 
| MB_YESNO
 
 328 // Fatal error: pop up message box and abort 
 331 , const wxString
&                   rTitle
 
 336     ulRc 
= ::WinMessageBox( HWND_DESKTOP
 
 343     DosExit(EXIT_PROCESS
, ulRc
); 
 349     DosBeep(1000,1000); // 1kHz during 1 sec. 
 352 // Chris Breeze 27/5/98: revised WIN32 code to 
 353 // detect WindowsNT correctly 
 359     ULONG                           ulSysInfo
[QSV_MAX
] = {0}; 
 362     ulrc 
= ::DosQuerySysInfo( 1L 
 365                              ,sizeof(ULONG
) * QSV_MAX
 
 369         *pMajorVsn 
= ulSysInfo
[QSV_VERSION_MAJOR
]; 
 370         *pMajorVsn 
= *pMajorVsn
/10; 
 371         *pMinorVsn 
= ulSysInfo
[QSV_VERSION_MINOR
]; 
 372         return wxWINDOWS_OS2
; 
 374     return wxWINDOWS
; // error if we get here, return generic value 
 377 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
 379 bool wxWriteResource( 
 380   const wxString
&                   rSection
 
 381 , const wxString
&                   rEntry
 
 382 , const wxString
&                   rValue
 
 383 , const wxString
&                   rFile
 
 391         hIni 
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
); 
 394             return (::PrfWriteProfileString( hIni
 
 395                                             ,(PSZ
)WXSTRINGCAST rSection
 
 396                                             ,(PSZ
)WXSTRINGCAST rEntry
 
 397                                             ,(PSZ
)WXSTRINGCAST rValue
 
 402         return (::PrfWriteProfileString( HINI_PROFILE
 
 403                                         ,(PSZ
)WXSTRINGCAST rSection
 
 404                                         ,(PSZ
)WXSTRINGCAST rEntry
 
 405                                         ,(PSZ
)WXSTRINGCAST rValue
 
 410 bool wxWriteResource( 
 411   const wxString
&                   rSection
 
 412 , const wxString
&                   rEntry
 
 414 , const wxString
&                   rFile
 
 419     wxSprintf(zBuf
, "%.4f", fValue
); 
 420     return wxWriteResource( rSection
 
 427 bool wxWriteResource( 
 428   const wxString
&                   rSection
 
 429 , const wxString
&                   rEntry
 
 431 , const wxString
&                   rFile
 
 436     wxSprintf(zBuf
, "%ld", lValue
); 
 437     return wxWriteResource( rSection
 
 444 bool wxWriteResource( 
 445   const wxString
&                   rSection
 
 446 , const wxString
&                   rEntry
 
 448 , const wxString
&                   rFile
 
 453     wxSprintf(zBuf
, "%d", lValue
); 
 454     return wxWriteResource( rSection
 
 462   const wxString
&                   rSection
 
 463 , const wxString
&                   rEntry
 
 465 , const wxString
&                   rFile
 
 470     wxChar                          zDefunkt
[] = _T("$$default"); 
 475         hIni 
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
); 
 478             ULONG n 
= ::PrfQueryProfileString( hIni
 
 479                                               ,(PSZ
)WXSTRINGCAST rSection
 
 480                                               ,(PSZ
)WXSTRINGCAST rEntry
 
 487             if (n 
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0) 
 496         ULONG n 
= ::PrfQueryProfileString( HINI_PROFILE
 
 497                                           ,(PSZ
)WXSTRINGCAST rSection
 
 498                                           ,(PSZ
)WXSTRINGCAST rEntry
 
 505         if (n 
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0) 
 509     strcpy((char*)*ppValue
, zBuf
); 
 514   const wxString
&                   rSection
 
 515 , const wxString
&                   rEntry
 
 517 , const wxString
&                   rFile
 
 522     zStr 
= new wxChar
[1000]; 
 523     bool                            bSucc 
= wxGetResource( rSection
 
 531         *pValue 
= (float)wxStrtod(zStr
, NULL
); 
 543   const wxString
&                   rSection
 
 544 , const wxString
&                   rEntry
 
 546 , const wxString
&                   rFile
 
 551     zStr 
= new wxChar
[1000]; 
 552     bool                              bSucc 
= wxGetResource( rSection
 
 560         *pValue 
= wxStrtol(zStr
, NULL
, 10); 
 572   const wxString
&                   rSection
 
 573 , const wxString
&                   rEntry
 
 575 , const wxString
&                   rFile
 
 580     zStr 
= new wxChar
[1000]; 
 581     bool                            bSucc 
= wxGetResource( rSection
 
 589         *pValue 
= (int)wxStrtol(zStr
, NULL
, 10); 
 599 #endif // wxUSE_RESOURCES 
 601 // --------------------------------------------------------------------------- 
 602 // helper functions for showing a "busy" cursor 
 603 // --------------------------------------------------------------------------- 
 605 HCURSOR gs_wxBusyCursor 
= 0;     // new, busy cursor 
 606 HCURSOR gs_wxBusyCursorOld 
= 0;  // old cursor 
 607 static int gs_wxBusyCursorCount 
= 0; 
 609 // Set the cursor to the busy cursor for all windows 
 610 void wxBeginBusyCursor( 
 614     if ( gs_wxBusyCursorCount
++ == 0 ) 
 616         gs_wxBusyCursor 
= (HCURSOR
)pCursor
->GetHCURSOR(); 
 617         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
); 
 619     //else: nothing to do, already set 
 622 // Restore cursor to normal 
 623 void wxEndBusyCursor() 
 625     wxCHECK_RET( gs_wxBusyCursorCount 
> 0 
 626                 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()") 
 629     if (--gs_wxBusyCursorCount 
== 0) 
 631         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
); 
 632         gs_wxBusyCursorOld 
= 0; 
 636 // TRUE if we're between the above two calls 
 639     return (gs_wxBusyCursorCount 
> 0); 
 642 // --------------------------------------------------------------------------- 
 643 const wxChar
* wxGetHomeDir( 
 647     wxString
&                       rStrDir 
= *pStr
; 
 649     // OS/2 has no idea about home, 
 650     // so use the working directory instead? 
 652     // 256 was taken from os2def.h 
 654 #  define MAX_PATH  256 
 660     ::DosQueryCurrentDir(0, zDirName
, &ulDirLen
); 
 662     return rStrDir
.c_str(); 
 666 wxChar
* wxGetUserHome ( 
 667   const wxString
&                   rUser
 
 671     wxString                        
sUser1(rUser
); 
 673     wxBuffer 
= new wxChar
[256]; 
 675     if (sUser1 
!= _T("")) 
 679         if (wxGetUserId( zTmp
 
 680                         ,sizeof(zTmp
)/sizeof(char) 
 683             // Guests belong in the temp dir 
 684             if (wxStricmp(zTmp
, _T("annonymous")) == 0) 
 686                 if ((zHome 
= wxGetenv(_T("TMP"))) != NULL    
|| 
 687                     (zHome 
= wxGetenv(_T("TMPDIR"))) != NULL 
|| 
 688                     (zHome 
= wxGetenv(_T("TEMP"))) != NULL
) 
 690                     return *zHome 
? zHome 
: (wxChar
*)_T("\\"); 
 692             if (wxStricmp(zTmp
, WXSTRINGCAST sUser1
) == 0) 
 697     if (sUser1 
== _T("")) 
 699         if ((zHome 
= wxGetenv(_T("HOME"))) != NULL
) 
 701             wxStrcpy(wxBuffer
, zHome
); 
 702             Unix2DosFilename(wxBuffer
); 
 703             wxStrcpy(zHome
, wxBuffer
); 
 709     return NULL
; // No home known! 
 712 // Check whether this window wants to process messages, e.g. Stop button 
 713 // in long calculations. 
 714 bool wxCheckForInterrupt( 
 722         HWND                        hwndFilter 
= NULLHANDLE
; 
 723         HWND                        hwndWin
= (HWND
) pWnd
->GetHWND(); 
 725         while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
)) 
 727             ::WinDispatchMsg(hab
, &vMsg
); 
 729         return TRUE
;//*** temporary? 
 733         wxFAIL_MSG(_T("pWnd==NULL !!!")); 
 734         return FALSE
;//*** temporary? 
 738 void wxGetMousePosition( 
 745     ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
); 
 750 // Return TRUE if we have a colour display 
 751 bool wxColourDisplay() 
 757     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 758     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 759     ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
); 
 760     return(lColors 
> 1L); 
 763 // Returns depth of screen 
 772     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 773     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 774     ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
); 
 775     ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
); 
 777     nDepth 
= (int)(lPlanes 
* lBitsPerPixel
); 
 778     DevCloseDC(hdcScreen
); 
 782 // Get size of display 
 793     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 794     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 795     ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
); 
 796     ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
); 
 797     DevCloseDC(hdcScreen
); 
 798     *pWidth 
= (int)lWidth
; 
 799     *pHeight 
= (int)lHeight
; 
 802 void wxDisplaySizeMM( 
 810     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 811     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 814         ::DevQueryCaps( hdcScreen
 
 815                        ,CAPS_HORIZONTAL_RESOLUTION
 
 820         ::DevQueryCaps( hdcScreen
 
 821                        ,CAPS_VERTICAL_RESOLUTION
 
 827 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 829     // This is supposed to return desktop dimensions minus any window 
 830     // manager panels, menus, taskbars, etc.  If there is a way to do that 
 831     // for this platform please fix this function, otherwise it defaults 
 832     // to the entire desktop. 
 835     wxDisplaySize(width
, height
); 
 843     return (::DosSetCurrentDir(WXSTRINGCAST rDir
)); 
 846 // --------------------------------------------------------------------------- 
 847 // window information functions 
 848 // --------------------------------------------------------------------------- 
 850 wxString WXDLLEXPORT 
wxGetWindowText( 
 855     long                            lLen 
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1; 
 857     ::WinQueryWindowText((HWND
)hWnd
, lLen
, vStr
.GetWriteBuf((int)lLen
)); 
 858     vStr
.UngetWriteBuf(); 
 863 wxString WXDLLEXPORT 
wxGetWindowClass( 
 868     int                             nLen 
= 256; // some starting value 
 872         int                         nCount 
= ::WinQueryClassName((HWND
)hWnd
, nLen
, vStr
.GetWriteBuf(nLen
)); 
 874         vStr
.UngetWriteBuf(); 
 877             // the class name might have been truncated, retry with larger 
 889 WXWORD WXDLLEXPORT 
wxGetWindowId( 
 893     return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
); 
 896 wxString WXDLLEXPORT 
wxPMErrorToStr( 
 903     // Remove the high order byte -- it is useless 
 905     vError 
&= 0x0000ffff; 
 908         case PMERR_INVALID_HWND
: 
 909             sError 
= wxT("Invalid window handle specified"); 
 912         case PMERR_INVALID_FLAG
: 
 913             sError 
= wxT("Invalid flag bit set"); 
 916         case PMERR_NO_MSG_QUEUE
: 
 917             sError 
= wxT("No message queue available"); 
 920         case PMERR_INVALID_PARM
: 
 921             sError 
= wxT("Parameter contained invalid data"); 
 924         case PMERR_INVALID_PARAMETERS
: 
 925             sError 
= wxT("Parameter value is out of range"); 
 928         case PMERR_PARAMETER_OUT_OF_RANGE
: 
 929             sError 
= wxT("Parameter value is out of range"); 
 932         case PMERR_INVALID_INTEGER_ATOM
: 
 933             sError 
= wxT("Not a valid atom"); 
 936         case PMERR_INVALID_HATOMTBL
: 
 937             sError 
= wxT("Atom table handle is invalid"); 
 940         case PMERR_INVALID_ATOM_NAME
: 
 941             sError 
= wxT("Not a valid atom name"); 
 944         case PMERR_ATOM_NAME_NOT_FOUND
: 
 945             sError 
= wxT("Valid name format, but cannot find name in atom table"); 
 949             sError 
= wxT("Unknown error"); 
 952 } // end of wxPMErrorToStr 
 962     vPoint
[0].x 
= rRect
.xLeft
; 
 963     vPoint
[0].y 
= rRect
.yBottom
; 
 964     ::GpiMove(hPS
, &vPoint
[0]); 
 965     if (dwStyle 
& wxSIMPLE_BORDER 
|| 
 966         dwStyle 
& wxSTATIC_BORDER
) 
 968         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 969         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 977     if (dwStyle 
& wxSUNKEN_BORDER
) 
 979         LINEBUNDLE                      vLineBundle
; 
 981         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 982         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 983         vLineBundle
.fxWidth    
= 2; 
 984         vLineBundle
.lGeomWidth 
= 2; 
 985         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 986         vLineBundle
.usEnd      
= 0; 
 987         vLineBundle
.usJoin     
= 0; 
 990                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 994         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 995         vPoint
[1].y 
= rRect
.yTop 
- 1; 
1002        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
1003        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
1004        ::GpiMove(hPS
, &vPoint
[0]); 
1005         vPoint
[1].x 
= rRect
.xRight 
- 2; 
1006         vPoint
[1].y 
= rRect
.yTop 
- 2; 
1014         vLineBundle
.lColor     
= 0x00000000; // BLACK 
1015         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
1016         vLineBundle
.fxWidth    
= 2; 
1017         vLineBundle
.lGeomWidth 
= 2; 
1018         vLineBundle
.usType     
= LINETYPE_SOLID
; 
1019         vLineBundle
.usEnd      
= 0; 
1020         vLineBundle
.usJoin     
= 0; 
1023                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
1027         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
1028         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
1029         ::GpiMove(hPS
, &vPoint
[0]); 
1030         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
1031         vPoint
[1].y 
= rRect
.yTop 
- 3; 
1032         ::GpiLine(hPS
, &vPoint
[1]); 
1033         vPoint
[1].x 
= rRect
.xRight 
- 3; 
1034         vPoint
[1].y 
= rRect
.yTop 
- 3; 
1035         ::GpiLine(hPS
, &vPoint
[1]); 
1037         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
1038         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
1039         ::GpiMove(hPS
, &vPoint
[0]); 
1040         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
1041         vPoint
[1].y 
= rRect
.yTop 
- 4; 
1042         ::GpiLine(hPS
, &vPoint
[1]); 
1043         vPoint
[1].x 
= rRect
.xRight 
- 4; 
1044         vPoint
[1].y 
= rRect
.yTop 
- 4; 
1045         ::GpiLine(hPS
, &vPoint
[1]); 
1047     if (dwStyle 
& wxDOUBLE_BORDER
) 
1049         LINEBUNDLE                      vLineBundle
; 
1051         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
1052         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
1053         vLineBundle
.fxWidth    
= 2; 
1054         vLineBundle
.lGeomWidth 
= 2; 
1055         vLineBundle
.usType     
= LINETYPE_SOLID
; 
1056         vLineBundle
.usEnd      
= 0; 
1057         vLineBundle
.usJoin     
= 0; 
1060                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
1064         vPoint
[1].x 
= rRect
.xRight 
- 1; 
1065         vPoint
[1].y 
= rRect
.yTop 
- 1; 
1072         vLineBundle
.lColor     
= 0x00000000; // WHITE 
1073         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
1074         vLineBundle
.fxWidth    
= 2; 
1075         vLineBundle
.lGeomWidth 
= 2; 
1076         vLineBundle
.usType     
= LINETYPE_SOLID
; 
1077         vLineBundle
.usEnd      
= 0; 
1078         vLineBundle
.usJoin     
= 0; 
1081                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
1085         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
1086         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
1087         ::GpiMove(hPS
, &vPoint
[0]); 
1088         vPoint
[1].x 
= rRect
.xRight 
- 2; 
1089         vPoint
[1].y 
= rRect
.yTop 
- 2; 
1096         vLineBundle
.lColor     
= 0x00FFFFFF; // BLACK 
1097         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
1098         vLineBundle
.fxWidth    
= 2; 
1099         vLineBundle
.lGeomWidth 
= 2; 
1100         vLineBundle
.usType     
= LINETYPE_SOLID
; 
1101         vLineBundle
.usEnd      
= 0; 
1102         vLineBundle
.usJoin     
= 0; 
1105                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
1109         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
1110         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
1111         ::GpiMove(hPS
, &vPoint
[0]); 
1112         vPoint
[1].x 
= rRect
.xRight 
- 3; 
1113         vPoint
[1].y 
= rRect
.yTop 
- 3; 
1121     if (dwStyle 
& wxRAISED_BORDER
) 
1123         LINEBUNDLE                      vLineBundle
; 
1125         vLineBundle
.lColor     
= 0x00000000; // BLACK 
1126         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
1127         vLineBundle
.fxWidth    
= 2; 
1128         vLineBundle
.lGeomWidth 
= 2; 
1129         vLineBundle
.usType     
= LINETYPE_SOLID
; 
1130         vLineBundle
.usEnd      
= 0; 
1131         vLineBundle
.usJoin     
= 0; 
1134                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
1138         vPoint
[1].x 
= rRect
.xRight 
- 1; 
1139         vPoint
[1].y 
= rRect
.yTop 
- 1; 
1146        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
1147        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
1148        ::GpiMove(hPS
, &vPoint
[0]); 
1149         vPoint
[1].x 
= rRect
.xRight 
- 2; 
1150         vPoint
[1].y 
= rRect
.yTop 
- 2; 
1158         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
1159         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
1160         vLineBundle
.fxWidth    
= 2; 
1161         vLineBundle
.lGeomWidth 
= 2; 
1162         vLineBundle
.usType     
= LINETYPE_SOLID
; 
1163         vLineBundle
.usEnd      
= 0; 
1164         vLineBundle
.usJoin     
= 0; 
1167                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
1171         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
1172         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
1173         ::GpiMove(hPS
, &vPoint
[0]); 
1174         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
1175         vPoint
[1].y 
= rRect
.yTop 
- 3; 
1176         ::GpiLine(hPS
, &vPoint
[1]); 
1177         vPoint
[1].x 
= rRect
.xRight 
- 3; 
1178         vPoint
[1].y 
= rRect
.yTop 
- 3; 
1179         ::GpiLine(hPS
, &vPoint
[1]); 
1181         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
1182         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
1183         ::GpiMove(hPS
, &vPoint
[0]); 
1184         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
1185         vPoint
[1].y 
= rRect
.yTop 
- 4; 
1186         ::GpiLine(hPS
, &vPoint
[1]); 
1187         vPoint
[1].x 
= rRect
.xRight 
- 4; 
1188         vPoint
[1].y 
= rRect
.yTop 
- 4; 
1189         ::GpiLine(hPS
, &vPoint
[1]); 
1191 } // end of wxDrawBorder