#include "wxinc.h" #include "oswin32.h" #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #define STRICT #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; } void* OsWin32_ConvertFromNativePrinterInfo(void* hGlobal, unsigned int& nDataSize) { void* ptr = ::GlobalLock(hGlobal); PDEVMODE dm = (PDEVMODE)ptr; nDataSize = dm->dmSize+dm->dmDriverExtra; void* buff = new char[nDataSize]; memcpy(buff, ptr, nDataSize); ::GlobalUnlock(hGlobal); return buff; } void* OsWin32_ConvertToNativePrinterInfo(void* data, unsigned int nDataSize) { HGLOBAL hGlobal = ::GlobalAlloc(GHND, nDataSize); void* ptr = ::GlobalLock(hGlobal); memcpy(ptr, data, nDataSize); ::GlobalUnlock(hGlobal); return hGlobal; } struct XvtData { char** families; long* sizes; short* scalable; long max_count; long 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; d->families[d->cur_count++] = strdup(plf->lfFaceName); return d->cur_count < 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; long& i = d->cur_count; const int size = (plf->lfHeight+5) / 10; 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 strcmp(s1, s2); } int OsWin32_EnumerateFamilies(unsigned int hDC, char** families, int max_count) { XvtData data; data.families = families; data.max_count = max_count; LOGFONT lf; memset(&lf, 0, sizeof(lf)); ::EnumFontFamiliesEx((HDC)hDC, &lf, FamilyEnumerator, (LPARAM)&data, 0); qsort(families, data.cur_count, sizeof(char*), FamilySorter); return data.cur_count; } int OsWin32_EnumerateSizes(unsigned int 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)); strcpy(lf.lfFaceName, name); ::EnumFontFamiliesEx((HDC)hDC, &lf, SizeEnumerator, (LPARAM)&data, 0); return data.cur_count; } void* OsWin32_GetPrinterInfo(int& size, const char* printer) { char name[256]; size = 0; if (printer == NULL || *printer == '\0') { if (::GetProfileString("windows", "device", ",,,", name, sizeof(name)) == 0) return NULL; char* comma = strchr(name, ','); if (comma) *comma = '\0'; } else strcpy(name, printer); LPDEVMODE pdm = (LPDEVMODE) new char[16*1024]; HANDLE hPrinter; if (::OpenPrinter(name, &hPrinter, NULL) == 0) return NULL; ::DocumentProperties(0, hPrinter, name, pdm, NULL, DM_OUT_BUFFER); ::ClosePrinter(hPrinter); size = pdm->dmSize + pdm->dmDriverExtra; return pdm; } void OsWin32_SetCaptionStyle(unsigned int handle, bool set) { HWND hwnd = (HWND)handle; DWORD s = ::GetWindowLong(hwnd, GWL_STYLE); if (set) s |= WS_CAPTION; else s &= ~WS_CAPTION; #if !wxCHECK_VERSION(2,3,2) s |= WS_CLIPSIBLINGS; #endif ::SetWindowLong(hwnd, GWL_STYLE, s); } void OsWin32_SetClippingRect(unsigned int hDC, int x, int y, int w, int h) { HDC hdc = (HDC)hDC; if (w > 0 && h > 0) { HRGN hrgn = ::CreateRectRgn(x, y, x+w, y+h); ::SelectClipRgn(hdc, hrgn); ::DeleteObject(hrgn); } else ::SelectClipRgn(hdc, NULL); } void OsWin32_UpdateWindow(unsigned int handle) { HWND hwnd = (HWND)handle; ::UpdateWindow(hwnd); } void OsWin32_StretchBlt(unsigned int hDst, int xd, int yd, int wd, int hd, unsigned int hSrc, int xs, int ys, int ws, int hs) { const int nColors = ::GetDeviceCaps((HDC)hDst, NUMCOLORS); ::SetStretchBltMode((HDC)hDst, nColors == 2 ? STRETCH_HALFTONE : STRETCH_DELETESCANS); ::StretchBlt((HDC)hDst, xd, yd, wd, hd, (HDC)hSrc, xs, ys, ws, hs, SRCCOPY); } /////////////////////////////////////////////////////////// // Drawing bitmaps /////////////////////////////////////////////////////////// void OsWin32_DrawBitmap(unsigned int hBitmap, unsigned int hDC, int xd, int yd, int wd, int hd, int xs, int ys, int ws, int hs) { const int nTechno = ::GetDeviceCaps((HDC)hDC, TECHNOLOGY); if (nTechno == DT_RASPRINTER) // Sto stampando! { BITMAPINFO bi; memset(&bi, 0, sizeof(bi)); BITMAPINFOHEADER& bih = bi.bmiHeader; bih.biSize = sizeof(bih); HDC hMemDC = ::CreateCompatibleDC(NULL); GetDIBits(hMemDC, (HBITMAP)hBitmap, 0, 0, NULL, &bi, DIB_RGB_COLORS); if (bih.biSizeImage > 0) { LPBYTE bits = new BYTE[bih.biSizeImage]; ::GetDIBits(hMemDC, (HBITMAP)hBitmap, 0, bih.biHeight, bits, &bi, DIB_RGB_COLORS); ::StretchDIBits((HDC)hDC, xd, yd, wd, hd, xs, ys, ws, hs, bits, &bi, DIB_RGB_COLORS, SRCCOPY); delete bits; } ::DeleteDC(hMemDC); } else { HDC hMemDC = ::CreateCompatibleDC((HDC)hDC); HGDIOBJ hOldBitmap = ::SelectObject(hMemDC, (HBITMAP)hBitmap); ::SetStretchBltMode((HDC)hDC, STRETCH_DELETESCANS); ::StretchBlt((HDC)hDC, xd, yd, wd, hd, hMemDC, xs, ys, ws, hs, SRCCOPY); ::SelectObject(hMemDC, hOldBitmap); ::DeleteDC(hMemDC); } }