2016-09-09 13:58:28 +00:00
# include "wxinc.h"
# include "wx/filename.h"
# include "wx/image.h"
# include "wx/paper.h"
# include "wx/printdlg.h"
# include "wx/msw/helpchm.h"
# include "oswin32.h"
# include "xvt_menu.h"
# include "xvt_help.h"
# include "xvtart.h"
# include "xvt_defs.h"
# include "xvt_env.h"
# include "xvt_type.h"
# include "xvtwin.h"
# include <aclapi.h>
# include <psapi.h>
# include <shlobj.h>
bool OsWin32_CheckPrinterInfo ( const void * data , unsigned int size )
{
bool ok = data ! = NULL ;
if ( ok )
{
LPDEVMODE pdm = ( LPDEVMODE ) data ;
const unsigned int s = pdm - > dmSize + pdm - > dmDriverExtra ;
ok = s > 0 & & s = = size ;
}
return ok ;
}
static int AdjustDevmodePlease ( PDEVMODE dm )
{
// Forse dovremmo fare una Black List su file delle stampanti incompatibili):
// 1) "NRG SP 4100N PCL 5e"
// 2) aggiungere qui le altre
// Ma per ora zappiamo tutti i driver troppo grandi (> 3Kb)
if ( dm - > dmDriverExtra > 3 * 1024 )
dm - > dmDriverExtra = 0 ;
// Controllo il formato della carta
wxPrintPaperType * paper = wxThePrintPaperDatabase - > FindPaperTypeByPlatformId ( dm - > dmPaperSize ) ;
if ( paper = = NULL )
{
dm - > dmFields | = DM_PAPERSIZE ;
wxThePrintPaperDatabase - > WXADDPAPER ( ( wxPaperSize ) dm - > dmPaperSize /*wxPAPER_NONE*/ , dm - > dmPaperSize ,
dm - > dmFormName , dm - > dmPaperWidth , dm - > dmPaperLength ) ;
}
return dm - > dmSize + dm - > dmDriverExtra ;
}
void * OsWin32_ConvertFromNativePrinterInfo ( void * hGlobal , unsigned int & nDataSize )
{
void * buff = NULL ;
if ( hGlobal ! = NULL )
{
PDEVMODE dm = ( PDEVMODE ) : : GlobalLock ( hGlobal ) ;
nDataSize = AdjustDevmodePlease ( dm ) ;
buff = new char [ nDataSize ] ;
memcpy ( buff , dm , nDataSize ) ;
: : GlobalUnlock ( hGlobal ) ;
}
return buff ;
}
void * OsWin32_ConvertToNativePrinterInfo ( void * data , unsigned int nDataSize )
{
HGLOBAL hGlobal = : : GlobalAlloc ( GHND , nDataSize ) ; // Alloco lo spazio necessario
if ( hGlobal ! = NULL )
{
PDEVMODE dm = ( PDEVMODE ) : : GlobalLock ( hGlobal ) ; // Trasformo l'handle in puntatore
memcpy ( dm , data , nDataSize ) ; // Ricopio i dati della stampante
const unsigned int sz = AdjustDevmodePlease ( dm ) ; // Metto a posto parametri non standard
wxASSERT ( nDataSize = = sz ) ;
: : GlobalUnlock ( hGlobal ) ; // Libero il lock sull'handle
}
return hGlobal ;
}
struct XvtData
{
char * * families ;
long * sizes ;
short * scalable ;
int max_count ;
int cur_count ;
XvtData ( ) { memset ( this , 0 , sizeof ( XvtData ) ) ; }
} ;
int CALLBACK FamilyEnumerator (
const LOGFONT * plf , // pointer to logical-font data
const TEXTMETRIC * WXUNUSED ( lpntme ) , // pointer to physical-font data
unsigned long WXUNUSED ( FontType ) , // type of font
LPARAM lParam // application-defined data
)
{
XvtData * d = ( XvtData * ) lParam ;
int & n = d - > cur_count ;
int i ;
for ( i = n - 1 ; i > = 0 & & wxStricmp ( d - > families [ i ] , plf - > lfFaceName ) ; i - - ) ;
if ( i < 0 ) // Controlla che il nome del font non ci sia gia'
d - > families [ n + + ] = wxStrdup ( plf - > lfFaceName ) ;
return n < d - > max_count ;
}
int CALLBACK SizeEnumerator (
const LOGFONT * plf , // pointer to logical-font data
const TEXTMETRIC * lpntme , // pointer to physical-font data
unsigned long WXUNUSED ( FontType ) , // type of font
LPARAM lParam // application-defined data
)
{
XvtData * d = ( XvtData * ) lParam ;
int & i = d - > cur_count ;
int size = ( plf - > lfHeight + 5 ) / 10 ;
if ( size < = 0 )
{
for ( const char * n = plf - > lfFaceName ; * n ; n + + )
if ( * n > = ' 1 ' & & * n < = ' 9 ' )
{
size = int ( 120.0 / atoi ( n ) + 0.5 ) ;
break ;
}
if ( size < = 0 )
size = 12 ;
}
if ( i = = 0 | | size > d - > sizes [ i - 1 ] )
{
d - > sizes [ i ] = size ;
if ( lpntme - > tmPitchAndFamily & TMPF_TRUETYPE )
* d - > scalable = TRUE ;
i + + ;
}
return i < d - > max_count ;
}
int FamilySorter ( const void * p1 , const void * p2 )
{
const char * s1 = * ( const char * * ) p1 ;
const char * s2 = * ( const char * * ) p2 ;
return wxStricmp ( s1 , s2 ) ;
}
int OsWin32_EnumerateFamilies ( WXHDC hDC , char * * families , int max_count )
{
XvtData data ;
data . families = families ;
data . max_count = max_count ;
LOGFONT lf ; memset ( & lf , 0 , sizeof ( lf ) ) ;
lf . lfCharSet = DEFAULT_CHARSET ;
: : EnumFontFamiliesEx ( ( HDC ) hDC , & lf , FamilyEnumerator , ( LPARAM ) & data , 0 ) ;
qsort ( families , data . cur_count , sizeof ( char * ) , FamilySorter ) ;
return data . cur_count ;
}
int OsWin32_EnumerateSizes ( WXHDC hDC , const char * name , long * sizes , short * scalable , int max_count )
{
XvtData data ;
data . sizes = sizes ;
data . scalable = scalable ;
data . max_count = max_count ;
LOGFONT lf ; memset ( & lf , 0 , sizeof ( lf ) ) ;
lf . lfCharSet = DEFAULT_CHARSET ;
strcpy ( lf . lfFaceName , name ) ;
: : EnumFontFamiliesEx ( ( HDC ) hDC , & lf , SizeEnumerator , ( LPARAM ) & data , 0 ) ;
return data . cur_count ;
}
void * OsWin32_GetPrinterInfo ( int & size , const char * printer )
{
LPDEVMODE pdm = NULL ;
size = 0 ;
char name [ _MAX_PATH ] = " " ;
if ( printer = = NULL | | * printer = = ' \0 ' )
{
unsigned long namelen = _MAX_PATH ;
: : GetDefaultPrinter ( name , & namelen ) ;
}
else
wxStrncpy ( name , printer , sizeof ( name ) ) ;
HANDLE hPrinter = NULL ;
if ( : : OpenPrinter ( name , & hPrinter , NULL ) )
{
size = : : DocumentProperties ( 0 , hPrinter , name , NULL , NULL , 0 ) ; // Determina dimensione DEVMODE
if ( size > 0 )
{
pdm = ( LPDEVMODE ) new BYTE [ size ] ; // Alloca un DEVMODE sufficientemente capiente
memset ( pdm , 0 , size ) ; // Azzera tutto per bene
: : DocumentProperties ( 0 , hPrinter , name , pdm , NULL , DM_OUT_BUFFER ) ; // Legge DEVMODE
size = AdjustDevmodePlease ( pdm ) ;
}
else
size = 0 ;
: : ClosePrinter ( hPrinter ) ;
}
return pdm ;
}
void OsWin32_SetCaptionStyle ( WXHWND handle , long style )
{
HWND hWnd = ( HWND ) handle ;
LONG s = : : GetWindowLong ( hWnd , GWL_STYLE ) ;
if ( style & wxSYSTEM_MENU )
s | = WS_CAPTION ;
else
s & = ~ WS_CAPTION ;
if ( style & wxCLOSE_BOX )
s | = WS_SYSMENU ;
else
s & = ~ WS_SYSMENU ;
s | = WS_CLIPSIBLINGS ; // Forzatura necessaria da wx261
: : SetWindowLong ( hWnd , GWL_STYLE , s ) ;
if ( style & wxCLOSE_BOX )
{
HMENU hMenu = : : GetSystemMenu ( hWnd , FALSE ) ;
: : EnableMenuItem ( hMenu , SC_CLOSE , MF_BYCOMMAND | MF_ENABLED ) ;
WXHICON hIcon = xvtart_GetIconResource ( 0 ) . GetHICON ( ) ;
: : SendMessage ( hWnd , WM_SETICON , ICON_SMALL , ( LPARAM ) hIcon ) ;
}
}
///////////////////////////////////////////////////////////
// Drawing bitmaps
///////////////////////////////////////////////////////////
HBITMAP OsWin32_CreateBitmap ( const wxImage & img , wxDC & dc )
{
static wxPalette pal ;
HDC hDC = ( HDC ) dc . GetHDC ( ) ;
int nDepth = dc . GetDepth ( ) ;
// Altrimenti le stampanti in B/N perdono i toni di grigio
if ( nDepth = = 1 & & ! OsWin32_IsWindowsServer ( ) )
{
hDC = NULL ;
nDepth = 24 ;
}
if ( nDepth = = 8 )
{
if ( ! pal . Ok ( ) )
{
unsigned char red [ 256 ] , green [ 256 ] , blue [ 256 ] ;
PALETTEENTRY pe [ 256 ] ; memset ( pe , 0 , sizeof ( pe ) ) ;
UINT nEntries = : : GetSystemPaletteEntries ( hDC , 0 , 256 , pe ) ;
for ( UINT i = 0 ; i < nEntries ; i + + )
{
red [ i ] = pe [ i ] . peRed ;
green [ i ] = pe [ i ] . peGreen ;
blue [ i ] = pe [ i ] . peBlue ;
}
pal . Create ( nEntries , red , green , blue ) ;
}
dc . SetPalette ( pal ) ;
}
const int nWidth = img . GetWidth ( ) ;
const int nHeight = img . GetHeight ( ) ;
int nBytesPerLine = 0 ;
int nPadding = 0 ;
int nBitCount = 24 ;
switch ( nDepth )
{
case 32 : // Better if > Win98 :-) too
nBitCount = 32 ;
nBytesPerLine = nWidth * 4 ;
break ;
default :
nBytesPerLine = nWidth * 3 ;
break ;
}
const int nResto = nBytesPerLine % 4 ;
if ( nResto ! = 0 )
{
nPadding = 4 - nResto ;
nBytesPerLine + = nPadding ;
}
const int nImageSize = nHeight * nBytesPerLine ;
// Create the DIB section
unsigned char * pbits = ( unsigned char * ) calloc ( nImageSize , 1 ) ;
const size_t bi_size = sizeof ( BITMAPINFOHEADER ) ;
BITMAPINFO * bi = ( BITMAPINFO * ) calloc ( bi_size , 1 ) ;
bi - > bmiHeader . biSize = bi_size ;
bi - > bmiHeader . biWidth = nWidth ;
bi - > bmiHeader . biHeight = - nHeight ;
bi - > bmiHeader . biCompression = BI_RGB ;
bi - > bmiHeader . biPlanes = 1 ;
bi - > bmiHeader . biBitCount = nBitCount ;
bi - > bmiHeader . biSizeImage = nImageSize ;
switch ( nBitCount )
{
case 24 :
{
unsigned char * d = img . GetData ( ) ;
unsigned char * p = pbits ;
for ( int y = 0 ; y < nHeight ; y + + )
{
for ( int x = 0 ; x < nWidth ; x + + )
{
* ( p + + ) = * ( d + 2 ) ;
* ( p + + ) = * ( d + 1 ) ;
* ( p + + ) = * ( d + 0 ) ;
d + = 3 ;
}
for ( int i = 0 ; i < nPadding ; i + + )
* ( p + + ) = 0 ;
}
}
break ;
case 32 :
{
unsigned char * d = img . GetData ( ) ;
unsigned char * p = pbits ;
for ( int y = 0 ; y < nHeight ; y + + )
{
for ( int x = 0 ; x < nWidth ; x + + )
{
* ( p + + ) = * ( d + 2 ) ;
* ( p + + ) = * ( d + 1 ) ;
* ( p + + ) = * ( d + 0 ) ;
* ( p + + ) = 0 ;
d + = 3 ;
}
}
}
break ;
default :
break ;
}
HBITMAP hBitmap = : : CreateCompatibleBitmap ( hDC , nWidth , nHeight ) ;
if ( hBitmap )
{
HDC memdc = : : CreateCompatibleDC ( hDC ) ;
HBITMAP hOldBitmap = ( HBITMAP ) : : SelectObject ( memdc , hBitmap ) ;
HPALETTE hOldPalette = NULL ;
if ( nDepth = = 8 )
{
hOldPalette = : : SelectPalette ( memdc , ( HPALETTE ) pal . GetHPALETTE ( ) , FALSE ) ;
: : RealizePalette ( memdc ) ;
}
: : StretchDIBits ( memdc , 0 , 0 , nWidth , nHeight , 0 , 0 , nWidth , nHeight , pbits , bi , DIB_RGB_COLORS , SRCCOPY ) ;
if ( hOldBitmap )
: : SelectObject ( memdc , hOldBitmap ) ;
if ( hOldPalette )
: : SelectPalette ( memdc , hOldPalette , FALSE ) ;
: : DeleteDC ( memdc ) ;
}
free ( pbits ) ;
free ( bi ) ;
return hBitmap ;
}
bool OsWin32_DrawBitmap ( HBITMAP hBMP , wxDC & dc , const wxRect & dst , const wxRect & src )
{
static wxPalette pal ;
bool ok = hBMP ! = NULL ;
if ( ok )
{
HDC hDC = ( HDC ) dc . GetHDC ( ) ;
const int nTechno = : : GetDeviceCaps ( hDC , TECHNOLOGY ) ;
HDC hMemDC = NULL ;
if ( OsWin32_IsWindowsServer ( ) )
hMemDC = : : CreateCompatibleDC ( hDC ) ; // Per Terminal Server devo fare cosi'
else
hMemDC = : : CreateCompatibleDC ( NULL ) ; // Per gli altri sistemi devo fare cosa'
BITMAP bmp ; : : GetObject ( hBMP , sizeof ( bmp ) , & bmp ) ;
if ( nTechno = = DT_RASPRINTER ) // Sto stampando!
{
const size_t bi_size = sizeof ( BITMAPINFOHEADER ) + 256 * sizeof ( RGBQUAD ) ;
BITMAPINFO * bi = ( BITMAPINFO * ) calloc ( bi_size , 1 ) ; // Alloca ed azzera
BITMAPINFOHEADER & bih = bi - > bmiHeader ;
bih . biSize = sizeof ( bih ) ;
GetDIBits ( hMemDC , hBMP , 0 , bmp . bmHeight , NULL , bi , DIB_RGB_COLORS ) ;
ok = bih . biSizeImage > 0 ;
if ( ok )
{
LPBYTE bits = new BYTE [ bih . biSizeImage ] ;
: : GetDIBits ( hMemDC , hBMP , 0 , src . height , bits , bi , DIB_RGB_COLORS ) ;
: : StretchDIBits ( hDC , dst . x , dst . y , dst . width , dst . height , src . x , src . y , src . width , src . height ,
bits , bi , DIB_RGB_COLORS , SRCCOPY ) ;
delete bits ;
}
free ( bi ) ;
}
else
{
HGDIOBJ hOldBitmap = : : SelectObject ( hMemDC , hBMP ) ;
: : SetStretchBltMode ( hDC , HALFTONE ) ;
: : StretchBlt ( hDC , dst . x , dst . y , dst . width , dst . height ,
hMemDC , src . x , src . y , src . width , src . height , SRCCOPY ) ;
: : SelectObject ( hMemDC , hOldBitmap ) ;
}
: : DeleteDC ( hMemDC ) ;
}
return ok ;
}
void OsWin32_DrawDottedRect ( WXHDC hDC , int left , int top , int right , int bottom )
{
LOGBRUSH lBrush ;
lBrush . lbHatch = 0 ; lBrush . lbStyle = BS_SOLID ;
lBrush . lbColor = : : GetTextColor ( ( HDC ) hDC ) ;
HPEN hPen = : : ExtCreatePen ( PS_COSMETIC | PS_ALTERNATE , 1 , & lBrush , 0 , NULL ) ;
HGDIOBJ hOldPen = : : SelectObject ( ( HDC ) hDC , hPen ) ;
HGDIOBJ hBrush = : : GetStockObject ( HOLLOW_BRUSH ) ;
HGDIOBJ hOldBrush = : : SelectObject ( ( HDC ) hDC , hBrush ) ;
: : Rectangle ( ( HDC ) hDC , left , top , right , bottom ) ;
: : SelectObject ( ( HDC ) hDC , hOldBrush ) ;
: : SelectObject ( ( HDC ) hDC , hOldPen ) ;
: : DeleteObject ( hPen ) ;
}
void OsWin32_Beep ( int severity )
{
switch ( severity )
{
case 1 : : : MessageBeep ( MB_ICONEXCLAMATION ) ; break ;
case 2 : : : MessageBeep ( MB_ICONSTOP ) ; break ;
default : : : MessageBeep ( MB_OK ) ; break ;
}
}
static wxString GetHelpDir ( )
{ return " htmlhelp/ " ; }
static wxString FindHelpFile ( const char * topic )
{
wxString strTopic = topic ;
wxString strApp ;
wxFileName : : SplitPath ( wxTheApp - > argv [ 0 ] , NULL , & strApp , NULL ) ;
if ( strTopic . IsEmpty ( ) )
{
strTopic = strApp ;
strTopic + = " 100a " ;
}
wxString str ;
for ( int i = 0 ; i < 2 ; i + + )
{
str = GetHelpDir ( ) ;
str + = i = = 0 ? strTopic . Left ( 2 ) : strApp . Left ( 2 ) ;
str + = " help.pdf " ;
if ( : : wxFileExists ( str ) )
return str ;
}
for ( int i = 0 ; i < 2 ; i + + )
{
str = GetHelpDir ( ) ;
str + = i = = 0 ? strTopic . Left ( 2 ) : strApp . Left ( 2 ) ;
str + = " help.chm " ;
if ( : : wxFileExists ( str ) )
return str ;
}
for ( int i = 0 ; i < 2 ; i + + )
{
str = GetHelpDir ( ) ;
str + = i = = 0 ? strTopic . Left ( 2 ) : strApp . Left ( 2 ) ;
str + = " / " ;
str + = strTopic ;
str + = " .html " ;
if ( : : wxFileExists ( str ) )
return str ;
}
return wxEmptyString ;
}
int OsWin32_Help ( WXHWND handle , const char * hlp , unsigned int cmd , const char * topic )
{
wxString str = hlp ;
if ( str . IsEmpty ( ) | | ! wxFileExists ( str ) )
{
switch ( cmd )
{
case M_HELP_ONCONTEXT :
str = FindHelpFile ( topic ) ;
if ( wxFileExists ( str ) )
break ;
default :
str = FindHelpFile ( topic ) ;
if ( wxFileExists ( str ) )
{
topic = NULL ;
}
else
{
str = GetHelpDir ( ) ;
str + = " index.html " ;
}
break ;
}
}
if ( ! str . IsEmpty ( ) & & wxFileExists ( str ) )
{
if ( str . EndsWith ( " .pdf " ) )
{
wxString strCmd = OsWin32_File2App ( str ) ;
if ( topic & & * topic )
strCmd < < " /A nameddest= " < < topic ;
strCmd < < " " < < str ;
: : wxExecute ( strCmd ) ;
} else
if ( str . EndsWith ( " .chm " ) )
{
static wxCHMHelpController * hlp = new wxCHMHelpController ;
if ( hlp - > LoadFile ( str ) )
{
wxString strSection = topic ;
strSection + = " .html " ;
hlp - > DisplaySection ( strSection ) ;
}
} else
if ( str . EndsWith ( " .html " ) )
{
wxFileName fn = str ;
fn . MakeAbsolute ( ) ;
str = fn . GetFullPath ( ) ;
: : ShellExecute ( ( HWND ) handle , " open " , str , NULL , NULL , SW_SHOWNORMAL ) ;
}
return true ;
}
OsWin32_Beep ( 1 ) ; // Error beep
return false ;
}
///////////////////////////////////////////////////////////
// Execute in window support
///////////////////////////////////////////////////////////
struct TFindWindowInfo
{
HINSTANCE _instance ;
wxString _file ;
HWND _hwnd ;
TFindWindowInfo ( ) : _instance ( NULL ) , _hwnd ( NULL ) { }
} ;
static BOOL CALLBACK EnumWindowsProc ( HWND hwnd , LPARAM lParam )
{
TFindWindowInfo * w = ( TFindWindowInfo * ) lParam ;
if ( w - > _instance ! = NULL )
{
HINSTANCE inst = ( HINSTANCE ) : : GetWindowLong ( hwnd , GWL_HINSTANCE ) ;
if ( inst = = w - > _instance )
{
// Cerco di capire se e' la finetra principale dal fatto che abbia la caption ed i bottoni di chiusura
const DWORD dwWanted = WS_CAPTION | WS_SYSMENU ;
const DWORD style = : : GetWindowLong ( hwnd , GWL_STYLE ) ;
if ( ( style & dwWanted ) = = dwWanted )
{
w - > _hwnd = hwnd ;
return FALSE ;
}
return TRUE ;
}
}
if ( ! w - > _file . IsEmpty ( ) )
{
char str [ _MAX_PATH ] ;
if ( : : GetWindowText ( hwnd , str , sizeof ( str ) ) )
{
wxString title = str ;
title . MakeUpper ( ) ;
if ( title . Find ( w - > _file ) > = 0 )
{
w - > _hwnd = hwnd ;
return FALSE ;
}
}
}
return TRUE ;
}
WXHINSTANCE OsWin32_ProcessModule ( const char * name )
{
WXHINSTANCE hModule = NULL ;
DWORD * aProcesses = NULL ;
DWORD nItems = 0 , nFound = 0 ;
for ( nItems = 256 ; ; nItems * = 2 )
{
DWORD cbNeeded = 0 ;
free ( aProcesses ) ;
aProcesses = ( DWORD * ) calloc ( nItems , sizeof ( DWORD ) ) ;
if ( ! EnumProcesses ( aProcesses , nItems * sizeof ( DWORD ) , & cbNeeded ) )
{
free ( aProcesses ) ;
return false ;
}
nFound = cbNeeded / sizeof ( DWORD ) ;
if ( nFound < nItems )
break ;
}
for ( DWORD i = 0 ; i < nFound & & ! hModule ; i + + ) if ( aProcesses [ i ] )
{
HANDLE hProcess = : : OpenProcess ( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ , FALSE , aProcesses [ i ] ) ;
if ( hProcess ! = NULL )
{
HMODULE hMod ; DWORD cbNeeded ;
if ( : : EnumProcessModules ( hProcess , & hMod , sizeof ( hMod ) , & cbNeeded ) )
{
TCHAR szProcessName [ MAX_PATH ] = { 0 } ;
: : GetModuleBaseName ( hProcess , hMod , szProcessName , sizeof ( szProcessName ) / sizeof ( TCHAR ) ) ;
if ( wxStricmp ( szProcessName , name ) = = 0 )
hModule = ( WXHINSTANCE ) hMod ;
}
// Release the handle to the process.
CloseHandle ( hProcess ) ;
}
}
free ( aProcesses ) ;
return hModule ;
}
void OsWin32_PlaceProcessInWindow ( unsigned int instance , const char * name , unsigned int parent )
{
TFindWindowInfo w ;
w . _instance = ( HINSTANCE ) instance ;
w . _file = name ;
w . _file . MakeUpper ( ) ;
for ( int i = 0 ; w . _hwnd = = NULL & & i < 20 ; i + + )
{
: : wxMilliSleep ( 500 ) ;
: : EnumWindows ( EnumWindowsProc , LPARAM ( & w ) ) ;
}
if ( w . _hwnd ! = NULL ) // L'ho trovata!
{
RECT rct ; : : GetClientRect ( ( HWND ) parent , & rct ) ;
: : SetParent ( w . _hwnd , ( HWND ) parent ) ;
const int fx = : : GetSystemMetrics ( SM_CXFRAME ) ;
const int fy = : : GetSystemMetrics ( SM_CYFRAME ) ;
int cy = : : GetSystemMetrics ( SM_CYCAPTION ) + GetSystemMetrics ( SM_CYBORDER ) ;
if ( : : GetMenu ( w . _hwnd ) ! = NULL )
cy + = : : GetSystemMetrics ( SM_CYMENU ) ;
: : SetWindowPos ( w . _hwnd , ( HWND ) parent , - fx , - fy - cy , rct . right + 2 * fx , rct . bottom + cy + 2 * fy , SWP_NOZORDER ) ;
}
}
static BOOL CALLBACK EnumCampoChildrenProc ( HWND hwnd , LPARAM lParam )
{
char str [ _MAX_PATH ] ;
if ( : : GetWindowText ( hwnd , str , sizeof ( str ) ) )
{
TFindWindowInfo * w = ( TFindWindowInfo * ) lParam ;
if ( w - > _file = = str ) // str == "__CAMPO_HOST_WINDOW__"
{
str [ 13 ] = ' \0 ' ; // Impedisce che questa finestra abbia altri figli indesiderati
: : SetWindowText ( hwnd , str ) ;
w - > _hwnd = hwnd ;
return FALSE ; // Fine della ricerca
}
}
return TRUE ; // Continua a cercare
}
static BOOL CALLBACK EnumCampoMenuChildrenProc ( HWND hwnd , LPARAM lParam )
{
char str [ _MAX_PATH ] ;
if ( : : GetWindowText ( hwnd , str , sizeof ( str ) ) )
{
if ( strstr ( str , " - " ) ! = NULL )
{
const TFindWindowInfo * w = ( TFindWindowInfo * ) lParam ;
: : EnumChildWindows ( hwnd , EnumCampoChildrenProc , lParam ) ;
if ( w - > _hwnd ! = NULL )
return FALSE ; // Fine della ricerca
}
}
return TRUE ; // Continua a cercare
}
unsigned int OsWin32_FindMenuContainer ( )
{
wxString strApp ;
wxFileName : : SplitPath ( wxTheApp - > argv [ 0 ] , NULL , & strApp , NULL ) ;
strApp . MakeLower ( ) ;
if ( strApp = = " ba0 " | | strApp = = " ba1 " | | strApp = = " ba7 " )
return 0 ; // Special programs that can't be hosted by ba0
TFindWindowInfo w ;
w . _file = " __CAMPO_HOST_WINDOW__ " ;
: : EnumWindows ( EnumCampoMenuChildrenProc , LPARAM ( & w ) ) ;
return ( unsigned int ) w . _hwnd ;
}
static BOOL CALLBACK CountChildrenProc ( HWND WXUNUSED ( hwnd ) , LPARAM lParam )
{
if ( lParam )
{
LONG * n = ( LONG * ) lParam ;
( * n ) + + ;
}
return TRUE ;
}
long OsWin32_GetChildrenCount ( unsigned int parent )
{
LONG n = 0 ;
: : EnumChildWindows ( ( HWND ) parent , CountChildrenProc , ( LPARAM ) & n ) ;
return n ;
}
static BOOL CALLBACK CloseChildrenProc ( HWND hwnd , LPARAM lParam )
{
: : PostMessage ( hwnd , WM_CLOSE , 0 , 0 ) ;
return CountChildrenProc ( hwnd , lParam ) ;
}
long OsWin32_CloseChildren ( unsigned int parent )
{
LONG n = 0 ;
: : EnumChildWindows ( ( HWND ) parent , CloseChildrenProc , ( LPARAM ) & n ) ;
return n ;
}
///////////////////////////////////////////////////////////
// Ex-Golem utilities
///////////////////////////////////////////////////////////
static long GetRegistryString ( HKEY key , const char * subkey , wxString & retstr )
{
HKEY hkey ;
long retval = : : RegOpenKey ( key , subkey , & hkey ) ;
if ( retval = = ERROR_SUCCESS )
{
char retdata [ _MAX_PATH ] ;
long datasize = sizeof ( retdata ) ;
: : RegQueryValue ( hkey , NULL , retdata , & datasize ) ;
: : RegCloseKey ( hkey ) ;
retstr = retdata ;
}
return retval ;
}
wxString OsWin32_File2App ( const char * filename )
{
wxString app ;
if ( * filename ! = ' . ' )
{
char retdata [ _MAX_PATH ] ;
HINSTANCE hinst = : : FindExecutable ( filename , " . " , retdata ) ;
DWORD * pinst = ( DWORD * ) hinst ;
UINT err = LOWORD ( pinst ) ;
if ( err > 32 )
app = retdata ;
}
if ( app . IsEmpty ( ) )
{
wxString ext ;
if ( * filename = = ' . ' )
ext = filename ;
else
{
wxSplitPath ( filename , NULL , NULL , & ext ) ;
if ( ! ext . StartsWith ( " . " ) )
ext = " . " + ext ;
}
ext . MakeLower ( ) ;
wxString key ;
if ( GetRegistryString ( HKEY_CLASSES_ROOT , ext , key ) = = ERROR_SUCCESS )
{
key < < " \\ shell \\ open \\ command " ;
if ( GetRegistryString ( HKEY_CLASSES_ROOT , key , key ) = = ERROR_SUCCESS )
{
key . Replace ( " \" " , " " ) ;
int pos = key . Find ( " %1 " ) ;
if ( pos > 0 )
key . Truncate ( pos ) ;
key . Trim ( false ) ; key . Trim ( true ) ;
app = key ;
}
}
}
return app ;
}
static bool IsInternetAddress ( const char * filename )
{
wxString url ( filename ) ; url . MakeLower ( ) ;
if ( url . StartsWith ( " http: " ) | | url . StartsWith ( " ftp: " ) )
return true ;
if ( url . Find ( " www. " ) > = 0 )
return true ;
wxString ext ; wxFileName : : SplitPath ( url , NULL , NULL , NULL , & ext ) ;
const char * const extensions [ ] = { " com " , " edu " , " eu " , " gov " , " it " , " mil " , " net " , " org " , NULL } ;
for ( int e = 0 ; extensions [ e ] ; e + + )
if ( ext = = extensions [ e ] )
return true ;
return false ;
}
wxIcon OsWin32_LoadIcon ( const char * filename )
{
int icon_number = 0 ;
wxString ext ;
if ( * filename = = ' . ' & & strlen ( filename ) < _MAX_EXT )
ext = filename ;
else
{
if ( IsInternetAddress ( filename ) )
ext = " .htm " ;
else
{
wxFileName : : SplitPath ( filename , NULL , NULL , NULL , & ext ) ;
if ( ! ext . StartsWith ( " . " ) )
ext . insert ( 0 , " . " ) ;
}
}
ext . MakeLower ( ) ;
wxString key ;
if ( ext ! = " .exe " )
{
if ( : : GetRegistryString ( HKEY_CLASSES_ROOT , ext , key ) = = ERROR_SUCCESS )
{
key < < " \\ DefaultIcon " ;
if ( : : GetRegistryString ( HKEY_CLASSES_ROOT , key , key ) = = ERROR_SUCCESS ) // Windows 95 only
{
const int comma = key . find ( ' , ' ) ;
if ( comma > 0 )
{
icon_number = atoi ( key . Mid ( comma + 1 ) ) ;
key . Truncate ( comma ) ;
}
}
else
{
key = OsWin32_File2App ( filename ) ;
if ( key . IsEmpty ( ) )
key = OsWin32_File2App ( " .htm " ) ;
}
}
}
else
key = filename ;
// Toglie eventuali parametri sulla riga si comando
const int ext_pos = key . Find ( " .exe " ) ;
if ( ext_pos > 0 )
key . Truncate ( ext_pos + 4 ) ;
wxString strFullName = key ;
if ( icon_number > 0 )
strFullName < < " ; " < < icon_number ;
wxIcon ico ( strFullName , wxBITMAP_TYPE_ICO ) ;
return ico ;
}
// action = [ open, edit, print ];
bool OsWin32_GotoUrl ( const char * url , const char * action )
{
bool ok = false ;
// Sarebbe meglio un flag esplicito, ma per ora attendiamo solo le stampe
if ( action & & wxStricmp ( action , " print " ) = = 0 )
{
SHELLEXECUTEINFO sei ; memset ( & sei , 0 , sizeof ( sei ) ) ;
sei . cbSize = sizeof ( sei ) ;
sei . fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT ;
sei . lpVerb = action ;
sei . lpFile = url ;
sei . nShow = SW_SHOWNORMAL ;
if ( : : ShellExecuteEx ( & sei ) )
{
if ( sei . hProcess ! = NULL )
{
: : WaitForSingleObject ( sei . hProcess , 0 ) ;
: : CloseHandle ( sei . hProcess ) ;
}
ok = true ;
}
} else
if ( wxStrstr ( url , " .jar " ) )
{
const wxFileName fn = url ;
wxString args ; args < < " -jar " < < fn . GetFullPath ( ) ;
HINSTANCE hinst = : : ShellExecute ( NULL , NULL , " java.exe " , args , fn . GetPath ( ) , SW_HIDE ) ; // Hide java console
DWORD winst = DWORD ( ( DWORD * ) hinst ) ; // Tutto 'sto giro per evitare un warning
ok = UINT ( winst ) > 32 ;
}
else
{
HINSTANCE hinst = : : ShellExecute ( NULL , action , url , NULL , NULL , SW_SHOWNORMAL ) ;
DWORD winst = DWORD ( ( DWORD * ) hinst ) ; // Tutto 'sto giro per evitare un warning
ok = UINT ( winst ) > 32 ;
}
return ok ;
}
# ifdef SPEECH_API
# include <sapi.h>
static ISpVoice * m_pVoice = NULL ;
bool OsWin32_InitializeSpeech ( )
{
if ( m_pVoice = = NULL )
CoCreateInstance ( CLSID_SpVoice , NULL , CLSCTX_ALL , IID_ISpVoice , ( void * * ) & m_pVoice ) ;
return m_pVoice ! = NULL ;
}
void OsWin32_DeinitializeSpeech ( )
{
if ( m_pVoice ! = NULL )
{
m_pVoice - > WaitUntilDone ( 1000 ) ;
m_pVoice - > Release ( ) ;
m_pVoice = NULL ;
}
}
bool OsWin32_Speak ( const char * text , bool async )
{
if ( m_pVoice ! = NULL )
{
WCHAR str [ 1204 ] ;
MultiByteToWideChar ( CP_ACP , 0 , text , - 1 , str , strlen ( text ) + 1 ) ;
if ( async )
m_pVoice - > Speak ( str , SPF_ASYNC | SPF_PURGEBEFORESPEAK , NULL ) ;
else
m_pVoice - > Speak ( str , SPF_PURGEBEFORESPEAK , NULL ) ;
return true ;
}
return false ;
}
# endif
int OsWin32_GetSessionId ( )
{
DWORD session = 0 ;
: : ProcessIdToSessionId ( : : GetCurrentProcessId ( ) , & session ) ;
return ( int ) session ;
// return WTSGetActiveConsoleSessionId(); // Always 1! :-(
}
bool OsWin32_IsWindowsServer ( )
{
return : : GetSystemMetrics ( SM_REMOTESESSION ) ! = 0 ;
}
void OsWin32_NumberFormat ( char * str , int size )
{
static char decsep = ' \0 ' , thosep = ' \0 ' ;
char buf [ 80 ] = " " ;
if ( ! decsep )
{
: : GetNumberFormat ( LOCALE_USER_DEFAULT , 0 , " 1936.27 " , NULL , buf , sizeof ( buf ) ) ;
decsep = buf [ strlen ( buf ) - 3 ] ;
thosep = buf [ 1 ] = = ' 9 ' ? ' \0 ' : buf [ 1 ] ;
}
if ( str & & * str )
{
int j = 0 ;
for ( int i = 0 ; str [ i ] ; i + + )
{
switch ( str [ i ] )
{
case ' . ' : buf [ j + + ] = decsep ; break ;
case ' , ' : break ; // Ignore thousand separator
default : buf [ j + + ] = str [ i ] ; break ;
}
}
buf [ j ] = ' \0 ' ;
wxStrncpy ( str , buf , size ) ;
}
}
///////////////////////////////////////////////////////////
// OsWin32_Progress...
///////////////////////////////////////////////////////////
static const wchar_t * str2wstr ( const char * str , int maxlen = - 1 )
{
static wchar_t wstr [ 260 ] ;
if ( str & & * str & & maxlen )
{
if ( maxlen < 0 | | maxlen > 256 )
maxlen = strlen ( str ) ;
wxConvCurrent - > ToWChar ( wstr , 260 , str , maxlen ) ;
}
else
wstr [ 0 ] = ' \0 ' ;
return wstr ;
}
class Win32ProgressIndicator
{
IProgressDialog * m_ppd ;
long _curr , _total , _perc ;
bool _cancellable ;
int _lines ;
clock_t _start ;
static int __nProgress ; // Instances
public :
bool IsOk ( ) const { return m_ppd ! = NULL ; }
bool SetProgress ( long curr , long tot ) ;
void SetText ( const char * msg ) ;
Win32ProgressIndicator ( WXHWND hwndParent , const char * strTitle , long nMax , bool bCanCancel ) ;
~ Win32ProgressIndicator ( ) ;
} ;
int Win32ProgressIndicator : : __nProgress = 0 ;
bool Win32ProgressIndicator : : SetProgress ( long nCurrent , long nTotal )
{
bool ok = IsOk ( ) ;
if ( ok )
{
if ( nCurrent < = 0 | | nTotal ! = _total )
{
m_ppd - > Timer ( PDTIMER_RESET , NULL ) ;
_start = clock ( ) ;
_perc = 0 ;
}
m_ppd - > SetProgress ( nCurrent , nTotal ) ;
_curr = nCurrent ;
_total = nTotal ;
if ( _lines < 2 )
{
const int newperc = nTotal > 0 & & nCurrent > 0 ? nCurrent * 100 / nTotal : 0 ;
if ( newperc ! = _perc )
{
_perc = newperc ;
const long nSec = ( clock ( ) - _start ) / CLOCKS_PER_SEC ;
if ( nSec > 0 )
{
2017-03-24 09:53:52 +00:00
// Trasformati i valori in float per evitare problemi, capitava che durante operazioni complesse nSpeed risultasse 0 per poi far crashare il programma 2 istruzioni dopo
const float nSpeed = ( float ) nCurrent / ( float ) nSec ;
const float nRemaining = ( float ) nTotal - nCurrent ;
const float remainingTime = nRemaining / nSpeed ; // <-- Qua
2016-09-09 13:58:28 +00:00
int s = nSec ;
const int h = s / 3600 ; s % = 3600 ;
const int m = s / 60 ; s % = 60 ;
wxString str ;
2016-09-26 22:41:18 +00:00
str = str . Format ( " %d%% - Trascorsi %02d:%02d:%02d " , _perc , h , m , s ) ;
if ( nSpeed < 120 )
2017-03-24 09:53:52 +00:00
str < < str . Format ( " - Velocit<69> %.2f/sec - %.0f sec.alla fine " , nSpeed , remainingTime ) ;
2016-09-09 13:58:28 +00:00
else
2016-09-26 22:41:18 +00:00
{
const int mins = remainingTime / 60 ;
2017-03-24 09:53:52 +00:00
str < < str . Format ( " - Velocit<69> %.2f/min " , nSpeed * 60 ) ;
2016-09-26 22:41:18 +00:00
if ( mins < 2 )
2017-03-24 09:53:52 +00:00
str < < str . Format ( " - %.0f sec.alla fine " , remainingTime ) ;
2016-09-26 22:41:18 +00:00
else
str < < str . Format ( " - %d min.alla fine " , mins ) ;
}
2016-09-09 13:58:28 +00:00
m_ppd - > SetLine ( 2 , str2wstr ( str ) , FALSE , NULL ) ;
}
}
}
if ( _cancellable & & m_ppd - > HasUserCancelled ( ) )
ok = false ;
}
return ok ;
}
void Win32ProgressIndicator : : SetText ( const char * msg )
{
if ( IsOk ( ) )
{
if ( msg & & * msg )
{
const char * acapo = strchr ( msg , ' \n ' ) ;
if ( acapo )
{
m_ppd - > SetLine ( 1 , str2wstr ( msg , acapo - msg ) , FALSE , NULL ) ;
m_ppd - > SetLine ( 2 , str2wstr ( acapo + 1 ) , FALSE , NULL ) ;
_lines = 2 ;
}
else
{
m_ppd - > SetLine ( 1 , str2wstr ( msg ) , FALSE , NULL ) ;
m_ppd - > SetLine ( 2 , L " " , FALSE , NULL ) ;
_lines = 1 ;
}
}
else
{
m_ppd - > SetLine ( 1 , L " " , FALSE , NULL ) ;
m_ppd - > SetLine ( 2 , L " " , FALSE , NULL ) ;
_lines = 0 ;
}
}
}
Win32ProgressIndicator : : Win32ProgressIndicator ( WXHWND hwndParent , const char * strTitle , long nMax , bool bCanCancel )
{
m_ppd = NULL ;
: : CoCreateInstance ( CLSID_ProgressDialog , NULL , CLSCTX_INPROC_SERVER , IID_IProgressDialog , ( void * * ) & m_ppd ) ;
if ( m_ppd )
{
if ( strTitle & & * strTitle )
m_ppd - > SetTitle ( str2wstr ( strTitle ) ) ; // Set the title of the dialog.
2016-09-26 22:41:18 +00:00
DWORD dwFlags = PROGDLG_NOTIME | PROGDLG_MODAL | PROGDLG_NOMINIMIZE ;
2016-09-09 13:58:28 +00:00
if ( nMax < = 1 )
{
if ( nMax = = 1 )
dwFlags | = PROGDLG_MARQUEEPROGRESS ;
else
dwFlags | = PROGDLG_NOPROGRESSBAR ;
}
_cancellable = bCanCancel & & nMax > 1 ;
if ( _cancellable )
m_ppd - > SetCancelMsg ( L " Attendere prego... " , NULL ) ; // Will only be displayed if Cancel button is pressed.
else
dwFlags | = PROGDLG_NOCANCEL ;
_lines = 0 ; // No text right now!
_perc = 0 ; // No progress right now
m_ppd - > StartProgressDialog ( ( HWND ) hwndParent , NULL , dwFlags , NULL ) ; // Display and enable automatic estimated time remaining.
m_ppd - > Timer ( PDTIMER_RESET , NULL ) ;
_start = clock ( ) ;
IOleWindow * m_wnd = NULL ;
if ( SUCCEEDED ( m_ppd - > QueryInterface ( IID_IOleWindow , ( void * * ) m_wnd ) ) )
{
HWND hwnd = NULL ;
if ( m_wnd & & SUCCEEDED ( m_wnd - > GetWindow ( & hwnd ) ) )
{
RECT rct ; : : GetWindowRect ( hwnd , & rct ) ;
const int x = rct . left ;
const int y = int ( ( 1.5 * __nProgress + 0.5 ) * ( rct . bottom - rct . top ) ) ;
: : SetWindowPos ( hwnd , NULL , x , y , 0 , 0 , SWP_NOSIZE | SWP_NOZORDER ) ;
WXHICON hIcon = xvtart_GetIconResource ( 0 ) . GetHICON ( ) ;
: : SendMessage ( hwnd , WM_SETICON , ICON_SMALL , ( LPARAM ) hIcon ) ;
}
}
__nProgress + + ;
}
}
Win32ProgressIndicator : : ~ Win32ProgressIndicator ( )
{
if ( m_ppd )
{
wxASSERT ( __nProgress > = 0 ) ;
m_ppd - > StopProgressDialog ( ) ;
m_ppd - > Release ( ) ;
m_ppd = NULL ;
__nProgress - - ;
}
}
WXHWND OsWin32_ProgressCreate ( WXHWND hwndParent , const char * strTitle , long nMax , bool bCanCancel )
{
Win32ProgressIndicator * pi = new Win32ProgressIndicator ( hwndParent , strTitle , nMax , bCanCancel ) ;
if ( pi & & ! pi - > IsOk ( ) )
{
delete pi ;
pi = NULL ;
}
return ( WXHWND ) pi ;
}
void OsWin32_ProgressDestroy ( WXHWND prog )
{
if ( prog )
{
Win32ProgressIndicator * ppd = ( Win32ProgressIndicator * ) prog ;
delete ppd ;
}
}
bool OsWin32_ProgressSetStatus ( WXHWND prog , long nCurrent , long nTotal )
{
bool ok = true ;
if ( prog )
{
Win32ProgressIndicator * ppd = ( Win32ProgressIndicator * ) prog ;
ok = ppd - > SetProgress ( nCurrent , nTotal ) ;
}
return ok ;
}
void OsWin32_ProgressSetText ( WXHWND prog , const char * msg )
{
Win32ProgressIndicator * pd = ( Win32ProgressIndicator * ) prog ;
if ( pd & & pd - > IsOk ( ) )
pd - > SetText ( msg ) ;
}