#include "wxinc.h" #include "wx/filename.h" #include "wx/image.h" #include "wx/paper.h" #include "oswin32.h" #include "aclapi.h" #include "xvt_menu.h" #include "xvt_help.h" #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #define STRICT #include #include #include 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 *lpntme, // pointer to physical-font data unsigned long 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++] = _strdup(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 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') { if (::GetProfileString("windows", "device", ",,,", name, sizeof(name)) == 0) return NULL; char* comma = strchr(name, ','); if (comma) *comma = '\0'; } 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); HICON hIcon = ::ExtractIcon(NULL, "res/campo.ico", 0); ::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 += "/"; str += strTopic; str += ".html"; if (wxFileExists(str)) break; } return str; } int OsWin32_Help(WXHWND handle, const char* hlp, unsigned int cmd, const char* topic) { wxString str; switch(cmd) { case M_HELP_ONCONTEXT: str = FindHelpFile(topic); if (wxFileExists(str)) break; default: str = GetHelpDir(); str += "index.html"; break; } if (!str.IsEmpty() && wxFileExists(str)) { ::ShellExecute((HWND)handle, "open", str, NULL, NULL, SW_SHOWDEFAULT); return true; } OsWin32_Beep(1); 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; } 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) { w->_hwnd = hwnd; return FALSE; } } return TRUE; } static BOOL CALLBACK EnumCampoMenuChildrenProc(HWND hwnd, LPARAM lParam) { char str[_MAX_PATH]; if (::GetWindowText(hwnd, str, sizeof(str))) { const wxString title = str; if (title.StartsWith("Base - ")) // Scandisco solo i figli del menu { ::EnumChildWindows(hwnd, EnumCampoChildrenProc, lParam); const TFindWindowInfo* w = (TFindWindowInfo*)lParam; if (w->_hwnd != NULL) return FALSE; } } return TRUE; } unsigned int OsWin32_FindMenuContainer() { TFindWindowInfo w; w._file = "__CAMPO_HOST_WINDOW__"; ::EnumWindows(EnumCampoMenuChildrenProc, LPARAM(&w)); return (unsigned int)w._hwnd; } static BOOL CALLBACK CountChildrenProc(HWND 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; } static BOOL CALLBACK CloseSiblingProc(HWND hwnd, LPARAM lParam) { if (hwnd != (HWND)lParam) { if (!::IsWindowVisible(hwnd)) { char str[256]; ::GetClassName(hwnd, str, sizeof(str)); if (strcmp(str, "wxWindowClassNR") == 0) { ::GetWindowText(hwnd, str, sizeof(str)); if (str[0] == '\0') { OsWin32_CloseChildren((UINT)hwnd); CloseChildrenProc(hwnd, 0L); } } } } return TRUE; } void OsWin32_CloseSiblings(unsigned int parent) { // NON FUNZIONA!!!!!!!!!!!!!!!!!!!!!!!!!!! // ::EnumWindows(CloseSiblingProc, parent); } /////////////////////////////////////////////////////////// // Hardlock Support /////////////////////////////////////////////////////////// #include "hlapi_c.h" bool OsWin32_HL_Login(unsigned short address, const unsigned char* label, const unsigned char* password) { int err = HL_LOGIN(address, LOCAL_DEVICE, (unsigned char*)label, (unsigned char*)password); return err == STATUS_OK; } bool OsWin32_HL_Logout() { HL_LOGOUT(); return TRUE; } bool OsWin32_HL_Read(unsigned short reg, unsigned short* data) { int err = HL_READ(reg, data); return err == STATUS_OK; } bool OsWin32_HL_ReadBlock(unsigned char* data) { int err = HL_READBL(data); return err == STATUS_OK; } bool OsWin32_HL_Write(unsigned short reg, unsigned short data) { int err = HL_WRITE(reg, data); return err == STATUS_OK; } bool OsWin32_HL_Crypt(unsigned short* data) // Array di 4 words (8 bytes) { int err = HL_CODE(data, 1); return err == STATUS_OK; } /////////////////////////////////////////////////////////// // Eutron Smartlink Support /////////////////////////////////////////////////////////// #include "skeylink.h" static KEY_NET _eutron_key; bool OsWin32_SL_Crypt(unsigned short* data) { _eutron_key.net_command = NET_KEY_ACCESS; _eutron_key.command = SCRAMBLING_MODE; memcpy(_eutron_key.data, data, 8); smartlink(&_eutron_key); if (_eutron_key.status == ST_OK) memcpy(data, _eutron_key.data, 8); return _eutron_key.status == ST_OK; } bool OsWin32_SL_Login(const unsigned char* label, const unsigned char* password) { memset(&_eutron_key, 0, sizeof(KEY_NET)); _eutron_key.net_command = NET_KEY_OPEN; _eutron_key.status = ST_HW_FAILURE; // Don't leave ST_OK = 0 here! memcpy(_eutron_key.label, label, strlen((const char*)label)); memcpy(_eutron_key.password, password, strlen((const char*)password)); smartlink(&_eutron_key); return _eutron_key.status == ST_OK; } bool OsWin32_SL_Logout() { _eutron_key.net_command = NET_KEY_CLOSE; _eutron_key.command = 0; smartlink(&_eutron_key); return true; } bool OsWin32_SL_ReadBlock(unsigned short reg, unsigned short size, unsigned short* data) { _eutron_key.net_command = NET_KEY_ACCESS; _eutron_key.command = BLOCK_READING_MODE; unsigned short* pointer = (unsigned short*)(&_eutron_key.data[0]); unsigned short* number = (unsigned short*)(&_eutron_key.data[2]); *pointer = reg; *number = size; smartlink(&_eutron_key); bool ok = _eutron_key.status == ST_OK; if (ok) memcpy(data, &_eutron_key.data[4], size*sizeof(unsigned short)); return ok; } bool OsWin32_SL_WriteBlock(unsigned short reg, unsigned short size, const unsigned short* data) { _eutron_key.net_command = NET_KEY_ACCESS; _eutron_key.command = BLOCK_WRITING_MODE; unsigned short* pointer = (unsigned short*)(&_eutron_key.data[0]); unsigned short* number = (unsigned short*)(&_eutron_key.data[2]); *pointer = reg; *number = size; memcpy(&_eutron_key.data[4], data, size*sizeof(unsigned short)); smartlink(&_eutron_key); return _eutron_key.status == ST_OK; } /////////////////////////////////////////////////////////// // 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); 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","gov","it","mil","net","org", NULL }; for (int e = 0; extensions[e]; e++) if (ext == extensions[e]) return true; return false; } unsigned int OsWin32_LoadIcon(const char* filename) { unsigned int icon = 0; 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); } 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); HINSTANCE hInst = NULL; HICON hicon = ::ExtractIcon(hInst, key, icon_number); if (hicon == NULL && icon_number != 0) hicon = ::ExtractIcon(hInst, key, 0); if (hicon != NULL) { DWORD dwicon = DWORD((DWORD*)hicon); icon = LOWORD(dwicon); } return icon; } // 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 && strcmp(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 { 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; } void OsWin32_SpoolNewLine(unsigned int hdc) { char output[4]; output[0] = 1; // Lunghezza: byte basso output[1] = 0; // Lunghezza: byte alto output[2] = '\n'; // A capo output[3] = 0; // Shwarzenegger ::Escape((HDC)hdc, PASSTHROUGH, 0, output, NULL ); } bool OsWin32_IsGenericTextOnly(void* data) { LPDEVMODE pdm = (LPDEVMODE)data; if (pdm->dmYResolution == 6) // Win 9x only return true; if (strstr((const char*)pdm->dmDeviceName, "eneric") != NULL) return true; return false; } #ifdef SPEECH_API #include "\Programmi\Microsoft Speech SDK 5.1\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 typedef BOOL (PASCAL *pfnProcessIdToSessionId)(DWORD dwProcessId,DWORD* pSessionId); int OsWin32_GetSessionId() { DWORD session = 0; #if _MSC_VER >= 1300 //modifiche del 1/2/08 per poter gestire le licenze con win2000/2003/2008 server edition ::ProcessIdToSessionId(GetCurrentProcessId(), &session); #else //modifiche del 5/4/04 per poter gestire le licenze con win2000/2003 server edition HMODULE kernel = GetModuleHandle("kernel32.dll"); if (kernel != NULL) { pfnProcessIdToSessionId fn = (pfnProcessIdToSessionId)GetProcAddress(kernel, "ProcessIdToSessionId"); if (fn != NULL) fn(GetCurrentProcessId(), &session); } #endif return (int)session; } //definito il valore della variabile intera SM_REMOTESESSION // che non esiste per WINVER < 0x500 #ifndef SM_REMOTESESSION #define SM_REMOTESESSION 0x1000 #endif bool OsWin32_IsWindowsServer() { return ::GetSystemMetrics(SM_REMOTESESSION) != 0; } void OsWin32_NumberFormat(char* str, int size) { char buf[80]; ::GetNumberFormat(LOCALE_USER_DEFAULT, 0, str, NULL, buf, sizeof(buf)); wxStrncpy(str, buf, size); }