Advertisement
Guest User

Untitled

a guest
Jun 6th, 2013
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.09 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <Wingdi.h>
  5. #include <winspool.h>
  6. #include <winuser.h>
  7. #include <mmsystem.h>
  8. #include <commctrl.h>
  9. #include <commdlg.h>
  10. #include <dlgs.h>
  11. #include <process.h>
  12. #include <prsht.h>
  13. #include <richedit.h>
  14. #include <shellapi.h>
  15. #include <Shlobj.h>
  16. #include <shlwapi.h>
  17. #include <ddraw.h>
  18. #include <shobjidl.h>
  19.  
  20. #include "sysconfig.h"
  21. #include "sysdeps.h"
  22.  
  23. #include "resource.h"
  24. #include "registry.h"
  25. #include "win32.h"
  26. #include "win32gui.h"
  27.  
  28. #define MAX_GUI_FONTS 2
  29. #define DEFAULT_FONTSIZE  8
  30.  
  31. static double multx, multy;
  32.  
  33. static TCHAR fontname_gui[32], fontname_list[32];
  34. static int fontsize_gui = DEFAULT_FONTSIZE;
  35. static int fontsize_list = DEFAULT_FONTSIZE;
  36. static int fontstyle_gui = 0;
  37. static int fontstyle_list = 0;
  38. static int fontweight_gui = FW_REGULAR;
  39. static int fontweight_list = FW_REGULAR;
  40.  
  41. static int listviews[16];
  42. static int listviewcnt;
  43. static HFONT listviewfont;
  44. static const TCHAR *fontprefix;
  45.  
  46. #include <pshpack2.h>
  47. typedef struct {
  48.     WORD dlgVer;
  49.     WORD signature;
  50.     DWORD helpID;
  51.     DWORD exStyle;
  52.     DWORD style;
  53.     WORD cDlgItems;
  54.     short x;
  55.     short y;
  56.     short cx;
  57.     short cy;
  58.     /*
  59.     sz_Or_Ord menu;
  60.     sz_Or_Ord windowClass;
  61.     WCHAR title[titleLen];
  62.     */
  63. } DLGTEMPLATEEX;
  64.  
  65. typedef struct {
  66.     WORD pointsize;
  67.     WORD weight;
  68.     BYTE italic;
  69.     BYTE charset;
  70.     WCHAR typeface[1];
  71. } DLGTEMPLATEEX_END;
  72.  
  73. typedef struct {
  74.     DWORD helpID;
  75.     DWORD exStyle;
  76.     DWORD style;
  77.     short x;
  78.     short y;
  79.     short cx;
  80.     short cy;
  81.     WORD id;
  82.     WORD reserved;
  83.     WCHAR windowClass[1];
  84.     /* variable data after this */
  85.     /* sz_Or_Ord title; */
  86.     /* WORD extraCount; */
  87. } DLGITEMTEMPLATEEX;
  88. #include <poppack.h>
  89.  
  90. static int font_vista_ok;
  91. static const wchar_t wfont_vista[] = _T("Segoe UI");
  92. static const wchar_t wfont_xp[] = _T("Tahoma");
  93. static const wchar_t wfont_old[] = _T("MS Sans Serif");
  94. static const TCHAR font_vista[] = _T("Segoe UI");
  95. static const TCHAR font_xp[] = _T("Tahoma");
  96.  
  97. static int align (double f)
  98. {
  99.     int v = (int)(f + 0.5);
  100.     return v;
  101. }
  102.  
  103. static int mmx (int v)
  104. {
  105.     return align ((v * multx) / 100.0 + 0.5);
  106. }
  107. static int mmy (int v)
  108. {
  109.     return align ((v * multy) / 100.0 + 0.5);
  110. }
  111.  
  112.  
  113. static BYTE *skiptextone (BYTE *s)
  114. {
  115.     s -= sizeof (WCHAR);
  116.     if (s[0] == 0xff && s[1] == 0xff) {
  117.         s += 4;
  118.         return s;
  119.     }
  120.     while (s[0] != 0 || s[1] != 0)
  121.         s += 2;
  122.     s += 2;
  123.     return s;
  124. }
  125.  
  126. static BYTE *skiptext (BYTE *s)
  127. {
  128.     if (s[0] == 0xff && s[1] == 0xff) {
  129.         s += 4;
  130.         return s;
  131.     }
  132.     while (s[0] != 0 || s[1] != 0)
  133.         s += 2;
  134.     s += 2;
  135.     return s;
  136. }
  137.  
  138. static BYTE *todword (BYTE *p)
  139. {
  140.     while ((LONG_PTR)p & 3)
  141.         p++;
  142.     return p;
  143. }
  144.  
  145. static void modifytemplate (DLGTEMPLATEEX *d, DLGTEMPLATEEX_END *d2, int id)
  146. {
  147.     d->cx = mmx (d->cx);
  148.     d->cy = mmy (d->cy);
  149. }
  150.  
  151. static void modifytemplatefont (DLGTEMPLATEEX *d, DLGTEMPLATEEX_END *d2)
  152. {
  153.     if (!wcscmp (d2->typeface, wfont_old)) {
  154.         wcscpy (d2->typeface, fontname_gui);
  155.         d2->pointsize = fontsize_gui;
  156.         d2->italic = (fontstyle_gui & ITALIC_FONTTYPE) != 0;
  157.         d2->weight = fontweight_gui;
  158. }
  159. }
  160.  
  161. static void modifyitem (DLGTEMPLATEEX *d, DLGTEMPLATEEX_END *d2, DLGITEMTEMPLATEEX *dt, int id)
  162. {
  163.     bool noyscale = false;
  164.  
  165.     if (dt->windowClass[0] != 0xffff && (!_tcsicmp (dt->windowClass, WC_LISTVIEWW) || !_tcsicmp (dt->windowClass, WC_TREEVIEWW)))
  166.         listviews[listviewcnt++] = dt->id;
  167.  
  168.     if (multy >= 89 && multy <= 111) {
  169.         int wc = 0;
  170.  
  171.         if (dt->windowClass[0] == 0xffff)
  172.             wc = dt->windowClass[1];
  173.  
  174.         if (wc == 0x0080 && dt->cy <= 20) // button
  175.             noyscale = true;
  176.         if (wc == 0x0085) // checkbox
  177.             noyscale = true;
  178.         if (wc == 0x0081 && dt->cy <= 20) // edit box
  179.             noyscale = true;
  180.     }
  181.  
  182.     if (!noyscale)
  183.         dt->cy = mmy (dt->cy);
  184.  
  185.     dt->cx = mmx (dt->cx);
  186.     dt->y = mmy (dt->y);
  187.     dt->x = mmx (dt->x);
  188. }
  189.  
  190. static INT_PTR CALLBACK DummyProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  191. {
  192.     switch(msg)
  193.     {
  194.     case WM_DESTROY:
  195.         PostQuitMessage (0);
  196.         return TRUE;
  197.     case WM_CLOSE:
  198.         DestroyWindow(hDlg);
  199.         return TRUE;
  200.     case WM_INITDIALOG:
  201.         return TRUE;
  202.     }
  203.     return FALSE;
  204. }
  205.  
  206. struct newresource *scaleresource (struct newresource *res, HWND parent, int resize)
  207. {
  208.     DLGTEMPLATEEX *d, *s;
  209.     DLGTEMPLATEEX_END *d2, *s2;
  210.     DLGITEMTEMPLATEEX *dt;
  211.     BYTE *p, *p2, *ps, *ps2;
  212.     int i;
  213.     struct newresource *ns;
  214.  
  215.     listviewcnt = 0;
  216.  
  217.     d = (DLGTEMPLATEEX*)res->resource;
  218.     d2 = (DLGTEMPLATEEX_END*)res->resource;
  219.  
  220.     if (d->dlgVer != 1 || d->signature != 0xffff)
  221.         return 0;
  222.     if (!(d->style & (DS_SETFONT | DS_SHELLFONT)))
  223.         return 0;
  224.  
  225.     ns = xcalloc (struct newresource, 1);
  226.     ns->inst = res->inst;
  227.     ns->size = res->size;
  228.     ns->tmpl = res->tmpl;
  229.     ns->resource = (LPCDLGTEMPLATEW)xmalloc (uae_u8, ns->size + 32);
  230.     memcpy ((void*)ns->resource, res->resource, ns->size);
  231.  
  232.     d = (DLGTEMPLATEEX*)ns->resource;
  233.     s = (DLGTEMPLATEEX*)res->resource;
  234.  
  235.     if (resize > 0) {
  236.         d->style &= ~DS_MODALFRAME;
  237.         d->style |= WS_THICKFRAME;
  238.     } else if (resize == 0) {
  239.         d->style |= DS_MODALFRAME;
  240.         d->style &= ~WS_THICKFRAME;
  241.     }
  242.  
  243.     d2 = (DLGTEMPLATEEX_END*)ns->resource;
  244.     p = (BYTE*)d + sizeof (DLGTEMPLATEEX);
  245.     p = skiptext (p);
  246.     p = skiptext (p);
  247.     p = skiptext (p);
  248.  
  249.     s2 = (DLGTEMPLATEEX_END*)res->resource;
  250.     ps = (BYTE*)s2 + sizeof (DLGTEMPLATEEX);
  251.     ps = skiptext (ps);
  252.     ps = skiptext (ps);
  253.     ps = skiptext (ps);
  254.  
  255.     d2 = (DLGTEMPLATEEX_END*)p;
  256.     p2 = p;
  257.     p2 += sizeof (DLGTEMPLATEEX_END);
  258.     p2 = skiptextone (p2);
  259.     p2 = todword (p2);
  260.  
  261.     s2 = (DLGTEMPLATEEX_END*)ps;
  262.     ps2 = ps;
  263.     ps2 += sizeof (DLGTEMPLATEEX_END);
  264.     ps2 = skiptextone (ps2);
  265.     ps2 = todword (ps2);
  266.  
  267.     modifytemplatefont (d, d2);
  268.  
  269.     p += sizeof (DLGTEMPLATEEX_END);
  270.     p = skiptextone (p);
  271.     p = todword (p);
  272.  
  273.     memcpy (p, ps2, ns->size - (ps2 - (BYTE*)res->resource));
  274.  
  275.     modifytemplate(d, d2, ns->tmpl);
  276.  
  277.     for (i = 0; i < d->cDlgItems; i++) {
  278.         dt = (DLGITEMTEMPLATEEX*)p;
  279.         modifyitem (d, d2, dt, ns->tmpl);
  280.         p += sizeof (DLGITEMTEMPLATEEX);
  281.         p = skiptextone (p);
  282.         p = skiptext (p);
  283.         p += ((WORD*)p)[0];
  284.         p += sizeof (WORD);
  285.         p = todword (p);
  286.     }
  287.  
  288.     ns->width = d->cx;
  289.     ns->height = d->cy;
  290.     return ns;
  291. }
  292.  
  293. void freescaleresource (struct newresource *ns)
  294. {
  295.     xfree ((void*)ns->resource);
  296.     xfree (ns);
  297. }
  298.  
  299. static void openfont (bool force)
  300. {
  301.     HDC hdc;
  302.     int size;
  303.  
  304.     if (listviewfont && !force)
  305.         return;
  306.     if (listviewfont)
  307.         DeleteObject (listviewfont);
  308.  
  309.     hdc = GetDC (NULL);
  310.  
  311.     size = -MulDiv (fontsize_list, GetDeviceCaps (hdc, LOGPIXELSY), 72);
  312.     listviewfont = CreateFont (size, 0, 0, 0, fontweight_list, (fontstyle_list & ITALIC_FONTTYPE) != 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontname_list);
  313.  
  314.     ReleaseDC (NULL, hdc);
  315. }
  316.  
  317. void scaleresource_setfont (HWND hDlg)
  318. {
  319.     if (!listviewcnt || (!_tcscmp (fontname_gui, fontname_list) && fontsize_gui == fontsize_list && fontstyle_gui == fontstyle_list && fontweight_gui == fontweight_list))
  320.         return;
  321.     openfont (false);
  322.     if (!listviewfont)
  323.         return;
  324.     for (int i = 0; i < listviewcnt; i++) {
  325.         SendMessage (GetDlgItem (hDlg, listviews[i]), WM_SETFONT, WPARAM(listviewfont), FALSE);
  326.     }
  327. }
  328.  
  329. static void setdeffont (void)
  330. {
  331.     _tcscpy (fontname_gui, font_vista_ok ? wfont_vista : wfont_xp);
  332.     fontsize_gui = DEFAULT_FONTSIZE;
  333.     fontstyle_gui = 0;
  334.     fontweight_gui = FW_REGULAR;
  335.     _tcscpy (fontname_list, font_vista_ok ? wfont_vista : wfont_xp);
  336.     fontsize_list = DEFAULT_FONTSIZE;
  337.     fontstyle_list = 0;
  338.     fontweight_list = FW_REGULAR;
  339. }
  340.  
  341. static TCHAR *fontreg[2] = { _T("GUIFont"), _T("GUIListFont") };
  342.  
  343. static void regsetfont (UAEREG *reg, const TCHAR *prefix, const TCHAR *name, const TCHAR *fontname, int fontsize, int fontstyle, int fontweight)
  344. {
  345.     TCHAR tmp[256], tmp2[256];
  346.  
  347.     _stprintf (tmp, _T("%s:%d:%d:%d"), fontname, fontsize, fontstyle, fontweight);
  348.     _stprintf (tmp2, _T("%s%s"), name, prefix);
  349.     regsetstr (reg, tmp2, tmp);
  350. }
  351. static void regqueryfont (UAEREG *reg, const TCHAR *prefix, const TCHAR *name, TCHAR *fontname, int *pfontsize, int *pfontstyle, int *pfontweight)
  352. {
  353.     TCHAR tmp2[256], tmp[256], *p1, *p2, *p3, *p4;
  354.     int size;
  355.     int fontsize, fontstyle, fontweight;
  356.  
  357.     _tcscpy (tmp2, name);
  358.     _tcscat (tmp2, prefix);
  359.     size = sizeof tmp / sizeof (TCHAR);
  360.     if (!regquerystr (reg, tmp2, tmp, &size))
  361.         return;
  362.     p1 = _tcschr (tmp, ':');
  363.     if (!p1)
  364.         return;
  365.     *p1++ = 0;
  366.     p2 = _tcschr (p1, ':');
  367.     if (!p2)
  368.         return;
  369.     *p2++ = 0;
  370.     p3 = _tcschr (p2, ':');
  371.     if (!p3)
  372.         return;
  373.     *p3++ = 0;
  374.     p4 = _tcschr (p3, ':');
  375.     if (p4)
  376.         *p4 = 0;
  377.  
  378.     _tcscpy (fontname, tmp);
  379.     fontsize = _tstoi (p1);
  380.     fontstyle = _tstoi (p2);
  381.     fontweight = _tstoi (p3);
  382.  
  383.     if (fontsize == 0)
  384.         fontsize = 8;
  385.     if (fontsize < 5)
  386.         fontsize = 5;
  387.     if (fontsize > 20)
  388.         fontsize = 20;
  389.     *pfontsize = fontsize;
  390.  
  391.     *pfontstyle = fontstyle;
  392.  
  393.     *pfontweight = fontweight;
  394. }
  395.  
  396. void scaleresource_setdefaults (void)
  397. {
  398.     setdeffont ();
  399.     for (int i = 0; i < MAX_GUI_FONTS; i++) {
  400.         TCHAR tmp[256];
  401.         _stprintf (tmp, _T("%s%s"), fontreg[i], fontprefix);
  402.         regdelete (NULL, tmp);
  403.     }
  404.     openfont (true);
  405. }
  406.  
  407. #define BASEMULT 1000
  408. static int baseunitx, baseunity;
  409. static RECT baserect, baseclientrect;
  410. static int baseborderwidth, baseborderheight;
  411. static int basewidth, baseheight;
  412. static int baseclientwidth, baseclientheight;
  413.  
  414. static INT_PTR CALLBACK TestProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  415. {
  416.     if (msg == WM_INITDIALOG) {
  417.         RECT r;
  418.         // there really is no better way?
  419.         r.left = 0;
  420.         r.top = 0;
  421.         r.bottom = BASEMULT;
  422.         r.right = BASEMULT;
  423.         MapDialogRect (hDlg, &r);
  424.         baseunitx = r.right * 4 / BASEMULT;
  425.         baseunity = r.bottom * 8 / BASEMULT;
  426.         GetWindowRect (hDlg, &baserect);
  427.         GetClientRect (hDlg, &baseclientrect);
  428.     }
  429.     return 0;
  430. }
  431.  
  432. // horrible or what?
  433. static void getbaseunits (void)
  434. {
  435.     struct newresource *nr, *nr2;
  436.     HWND hwnd;
  437.    
  438.     nr = getresource (IDD_PANEL);
  439.     if (!nr) {
  440.         write_log (_T("getbaseunits fail!\n"));
  441.         abort();
  442.     }
  443.     multx = multy = 100;
  444.     nr2 = scaleresource (nr, NULL, -1);
  445.     hwnd = CreateDialogIndirect (nr2->inst, nr2->resource, NULL, TestProc);
  446.     if (hwnd) {
  447.         DestroyWindow (hwnd);
  448.     } else {
  449.         baserect.left = baserect.top = 0;
  450.         baserect.right = 800;
  451.         baserect.bottom = 600;
  452.         baseclientrect.left = baseclientrect.top = 0;
  453.         baseclientrect.right = 800;
  454.         baseclientrect.bottom = 600;
  455.     }
  456.     freescaleresource (nr2);
  457.     freescaleresource (nr);
  458.     basewidth = baserect.right - baserect.left;
  459.     baseheight = baserect.bottom - baserect.top;
  460.     baseclientwidth = baseclientrect.right - baseclientrect.left;
  461.     baseclientheight = baseclientrect.bottom - baseclientrect.top;
  462.     baseborderwidth = basewidth - baseclientwidth;
  463.     baseborderheight = baseheight - baseclientheight;
  464.  
  465.     write_log (_T("GUIBase %dx%d (%dx%d)\n"), basewidth, baseheight, baseunitx, baseunity);
  466. }
  467.  
  468. void scaleresource_init (const TCHAR *prefix)
  469. {
  470.     if (os_vista)
  471.         font_vista_ok = 1;
  472.  
  473.     fontprefix = prefix;
  474.  
  475.     setdeffont ();
  476.  
  477.     regqueryfont (NULL, fontprefix, fontreg[0], fontname_gui, &fontsize_gui, &fontstyle_gui, &fontweight_gui);
  478.     regqueryfont (NULL, fontprefix, fontreg[1], fontname_list, &fontsize_list, &fontstyle_list, &fontweight_list);
  479.  
  480.     //write_log (_T("GUI font %s:%d:%d:%d\n"), fontname_gui, fontsize_gui, fontstyle_gui, fontweight_gui);
  481.     //write_log (_T("List font %s:%d:%d:%d\n"), fontname_list, fontsize_list, fontstyle_list, fontweight_list);
  482.  
  483.     getbaseunits ();
  484.  
  485.     openfont (true);
  486. }
  487.  
  488. #if 0
  489. static void sizefont (HWND hDlg, const TCHAR *name, int size, int style, int weight, int *width, int *height)
  490. {
  491.     /* ARGH!!! */
  492.  
  493.     HDC hdc = GetDC (hDlg);
  494.     size = -MulDiv (size, lpy, 72);
  495.     HFONT font = CreateFont (size, 0, 0, 0, weight,
  496.         (style & ITALIC_FONTTYPE) != 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, name);
  497.     if (!font) {
  498.         *width = 8;
  499.         *height = 8;
  500.     } else {
  501.         HFONT hFontOld = (HFONT)SelectObject (hdc, font);
  502.         TEXTMETRIC tm;
  503.         SIZE fsize;
  504.         GetTextMetrics (hdc, &tm);
  505.         GetTextExtentPoint32 (hdc, _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &fsize);
  506.         *width = (fsize.cx / 26 + 1) / 2;
  507.         *height = tm.tmHeight;
  508.         SelectObject (hdc, hFontOld);
  509.         DeleteObject (font);
  510.     }
  511.     ReleaseDC (hDlg, hdc);
  512. }
  513. #endif
  514.  
  515. double scaleresource_getdpimult (void)
  516. {
  517.     return (double)baseheight / GUI_INTERNAL_HEIGHT;
  518. }
  519.  
  520. void scaleresource_setmult (HWND hDlg, int w, int h)
  521. {
  522.     if (w < 0) {
  523.         multx = -w;
  524.         multy = -h;
  525.         return;
  526.     }
  527.  
  528.     multx = w * 100.0 / basewidth;
  529.     multy = h * 100.0 / baseheight;
  530.  
  531.     if (multx < 50)
  532.         multx = 50;
  533.     if (multy < 50)
  534.         multy = 50;
  535.  
  536.     //write_log (_T("MX=%f MY=%f\n"), multx, multy);
  537. }
  538.  
  539. void scaleresource_getmult (int *mx, int *my)
  540. {
  541.     if (mx)
  542.         *mx = (int)(multx + 0.5);
  543.     if (my)
  544.         *my = (int)(multy + 0.5);
  545. }
  546.  
  547.  
  548. int scaleresource_choosefont (HWND hDlg, int fonttype)
  549. {
  550.     CHOOSEFONT cf = { 0 };
  551.     LOGFONT lf = { 0 };
  552.     HDC hdc;
  553.     TCHAR *fontname[2];
  554.     int *fontsize[2], *fontstyle[2], *fontweight[2];
  555.     int lm;
  556.  
  557.     fontname[0] = fontname_gui;
  558.     fontname[1] = fontname_list;
  559.     fontsize[0] = &fontsize_gui;
  560.     fontsize[1] = &fontsize_list;
  561.     fontstyle[0] = &fontstyle_gui;
  562.     fontstyle[1] = &fontstyle_list;
  563.     fontweight[0] = &fontweight_gui;
  564.     fontweight[1] = &fontweight_list;
  565.  
  566.     cf.lStructSize = sizeof cf;
  567.     cf.hwndOwner = hDlg;
  568.     cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_NOSCRIPTSEL | CF_SCREENFONTS;
  569.     cf.lpLogFont = &lf;
  570.     cf.nFontType = REGULAR_FONTTYPE;
  571.     cf.iPointSize = *fontsize[fonttype];
  572.  
  573.     hdc = GetDC (NULL);
  574.     lm = GetDeviceCaps (hdc, LOGPIXELSY);
  575.  
  576.     _tcscpy (lf.lfFaceName, fontname[fonttype]);
  577.     lf.lfHeight = -MulDiv (*fontsize[fonttype], lm, 72);
  578.     lf.lfWeight = *fontweight[fonttype];
  579.     lf.lfItalic = (*fontstyle[fonttype] & ITALIC_FONTTYPE) != 0;
  580.  
  581.     if (!ChooseFont (&cf)) {
  582.         ReleaseDC (NULL, hdc);
  583.         return 0;
  584.     }
  585.  
  586.     _tcscpy (fontname[fonttype], lf.lfFaceName);
  587.     *fontsize[fonttype] = lf.lfHeight;
  588.     *fontsize[fonttype] = -MulDiv (*fontsize[fonttype], 72, GetDeviceCaps (hdc, LOGPIXELSY));
  589.  
  590.     *fontstyle[fonttype] = lf.lfItalic ? ITALIC_FONTTYPE : 0;
  591.  
  592.     *fontweight[fonttype] = lf.lfWeight;
  593.  
  594.     ReleaseDC (NULL, hdc);
  595.  
  596.     regsetfont (NULL, fontprefix, fontreg[fonttype], fontname[fonttype], *fontsize[fonttype], *fontstyle[fonttype], *fontweight[fonttype]);
  597.  
  598.     openfont (true);
  599.  
  600.  
  601.     return 1;
  602. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement