summaryrefslogtreecommitdiff
path: root/iup/src/win/iupwin_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'iup/src/win/iupwin_draw.c')
-rwxr-xr-xiup/src/win/iupwin_draw.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/iup/src/win/iupwin_draw.c b/iup/src/win/iupwin_draw.c
new file mode 100755
index 0000000..4a810e6
--- /dev/null
+++ b/iup/src/win/iupwin_draw.c
@@ -0,0 +1,328 @@
+/** \file
+ * \brief Draw Functions
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#include <windows.h>
+#include <uxtheme.h>
+#include <tmschema.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+#include "iup.h"
+
+#include "iup_attrib.h"
+#include "iup_class.h"
+#include "iup_str.h"
+
+#include "iupwin_drv.h"
+#include "iupwin_info.h"
+#include "iupwin_draw.h"
+
+
+#ifndef TABP_AEROWIZARDBODY
+#define TABP_AEROWIZARDBODY 11 /* manually added definition */
+#endif
+
+#ifndef TMT_FILLCOLORHINT
+#define TMT_FILLCOLORHINT 3821
+#endif
+#ifndef TMT_TEXTCOLOR
+#define TMT_TEXTCOLOR 3823
+#endif
+
+
+typedef HTHEME (STDAPICALLTYPE *_winThemeOpenData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (STDAPICALLTYPE *_winThemeCloseData)(HTHEME hTheme);
+typedef HRESULT (STDAPICALLTYPE *_winThemeDrawBackground)(HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
+typedef HRESULT (STDAPICALLTYPE *_winThemeGetColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, COLORREF *pColor);
+
+static _winThemeOpenData winThemeOpenData = NULL;
+static _winThemeCloseData winThemeCloseData = NULL;
+static _winThemeDrawBackground winThemeDrawBackground = NULL;
+static _winThemeGetColor winThemeGetColor = NULL;
+
+typedef BOOL (CALLBACK* _winAlphaBlendFunc)( HDC hdcDest,
+ int xoriginDest, int yoriginDest,
+ int wDest, int hDest, HDC hdcSrc,
+ int xoriginSrc, int yoriginSrc,
+ int wSrc, int hSrc,
+ BLENDFUNCTION ftn);
+static _winAlphaBlendFunc winAlphaBlend = NULL;
+
+static int winDrawThemeEnabled(void)
+{
+ return winThemeOpenData? 1: 0;
+}
+
+void iupwinDrawText(HDC hDC, const char* text, int x, int y, int width, int height, HFONT hFont, COLORREF fgcolor, int style)
+{
+ COLORREF oldcolor;
+ RECT rect;
+ HFONT hOldFont = SelectObject(hDC, hFont);
+
+ rect.left = x;
+ rect.top = y;
+ rect.right = x+width;
+ rect.bottom = y+height;
+
+ SetTextAlign(hDC, TA_TOP|TA_LEFT);
+ SetBkMode(hDC, TRANSPARENT);
+ oldcolor = SetTextColor(hDC, fgcolor);
+
+ DrawText(hDC, text, -1, &rect, style|DT_NOCLIP);
+
+ SelectObject(hDC, hOldFont);
+ SetTextColor(hDC, oldcolor);
+ SetBkMode(hDC, OPAQUE);
+}
+
+void iupwinDrawBitmap(HDC hDC, HBITMAP hBitmap, HBITMAP hMask, int x, int y, int width, int height, int bpp)
+{
+ HDC hMemDC = CreateCompatibleDC(hDC);
+ SelectObject(hMemDC, hBitmap);
+
+ if (bpp == 32 && winAlphaBlend)
+ {
+ BLENDFUNCTION blendfunc;
+ blendfunc.BlendOp = AC_SRC_OVER;
+ blendfunc.BlendFlags = 0;
+ blendfunc.SourceConstantAlpha = 0xFF;
+ blendfunc.AlphaFormat = AC_SRC_ALPHA;
+
+ winAlphaBlend(hDC, x, y, width, height,
+ hMemDC, 0, 0, width, height,
+ blendfunc);
+ }
+ else if (bpp == 8 && hMask)
+ MaskBlt(hDC, x, y, width, height,
+ hMemDC, 0, 0,
+ hMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
+ else
+ BitBlt(hDC, x, y, width, height,
+ hMemDC, 0, 0,
+ SRCCOPY);
+
+
+ DeleteDC(hMemDC);
+}
+
+void iupwinDrawInit(void)
+{
+ if (!winAlphaBlend)
+ {
+ HINSTANCE lib = LoadLibrary("Msimg32");
+ if (lib)
+ winAlphaBlend = (_winAlphaBlendFunc)GetProcAddress(lib, "AlphaBlend");
+ }
+
+ if (!winThemeOpenData && iupwin_comctl32ver6)
+ {
+ HMODULE hinstDll = LoadLibrary("uxtheme.dll");
+ if (hinstDll)
+ {
+ winThemeOpenData = (_winThemeOpenData)GetProcAddress(hinstDll, "OpenThemeData");
+ winThemeCloseData = (_winThemeCloseData)GetProcAddress(hinstDll, "CloseThemeData");
+ winThemeDrawBackground = (_winThemeDrawBackground)GetProcAddress(hinstDll, "DrawThemeBackground");
+ winThemeGetColor = (_winThemeGetColor)GetProcAddress(hinstDll, "GetThemeColor");
+ }
+ }
+}
+
+static int winDrawGetThemeStateId(int itemState)
+{
+ if (itemState & ODS_DISABLED)
+ return PBS_DISABLED;
+ else if (itemState & ODS_SELECTED)
+ return PBS_PRESSED;
+ else if (itemState & ODS_HOTLIGHT)
+ return PBS_HOT;
+ else if (itemState & ODS_DEFAULT)
+ return PBS_DEFAULTED;
+ else
+ return PBS_NORMAL;
+}
+
+static int winDrawThemeButtonBorder(HWND hWnd, HDC hDC, RECT *rect, UINT itemState)
+{
+ int iStateId;
+ HTHEME hTheme;
+
+ if (!winDrawThemeEnabled())
+ return 0;
+
+ hTheme = winThemeOpenData(hWnd, L"BUTTON");
+ if (!hTheme)
+ return 0;
+
+ iStateId = winDrawGetThemeStateId(itemState);
+
+ winThemeDrawBackground(hTheme, hDC, BP_PUSHBUTTON, iStateId, rect, NULL);
+
+ winThemeCloseData(hTheme);
+ return 1;
+}
+
+void iupwinDrawThemeFrameBorder(HWND hWnd, HDC hDC, RECT *rect, UINT itemState)
+{
+ int iStateId = GBS_NORMAL;
+ HTHEME hTheme;
+
+ if (!winDrawThemeEnabled())
+ return;
+
+ hTheme = winThemeOpenData(hWnd, L"BUTTON");
+ if (!hTheme)
+ return;
+
+ if (itemState & ODS_DISABLED)
+ iStateId = GBS_DISABLED;
+
+ winThemeDrawBackground(hTheme, hDC, BP_GROUPBOX, iStateId, rect, NULL);
+
+ winThemeCloseData(hTheme);
+}
+
+int iupwinDrawGetThemeTabsBgColor(HWND hWnd, COLORREF *color)
+{
+ HTHEME hTheme;
+ HRESULT ret;
+
+ if (!winDrawThemeEnabled())
+ return 0;
+
+ hTheme = winThemeOpenData(hWnd, L"TAB");
+ if (!hTheme)
+ return 0;
+
+ if (iupwinIsVista())
+ ret = winThemeGetColor(hTheme, TABP_AEROWIZARDBODY, TIS_NORMAL, TMT_FILLCOLORHINT, color);
+ else
+ ret = winThemeGetColor(hTheme, TABP_BODY, TIS_NORMAL, TMT_FILLCOLORHINT, color);
+
+ winThemeCloseData(hTheme);
+ return (ret == S_OK)? 1: 0;
+}
+
+int iupwinDrawGetThemeButtonBgColor(HWND hWnd, COLORREF *color)
+{
+ HTHEME hTheme;
+ HRESULT ret;
+
+ if (!winDrawThemeEnabled())
+ return 0;
+
+ hTheme = winThemeOpenData(hWnd, L"BUTTON");
+ if (!hTheme)
+ return 0;
+
+ ret = winThemeGetColor(hTheme, BP_PUSHBUTTON, PBS_NORMAL, TMT_FILLCOLORHINT, color);
+
+ winThemeCloseData(hTheme);
+ return (ret == S_OK)? 1: 0;
+}
+
+int iupwinDrawGetThemeFrameFgColor(HWND hWnd, COLORREF *color)
+{
+ HTHEME hTheme;
+ HRESULT ret;
+
+ if (!winDrawThemeEnabled())
+ return 0;
+
+ hTheme = winThemeOpenData(hWnd, L"BUTTON");
+ if (!hTheme)
+ return 0;
+
+ ret = winThemeGetColor(hTheme, BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, color);
+
+ winThemeCloseData(hTheme);
+ return (ret == S_OK)? 1: 0;
+}
+
+static int winDrawGetStateId(int itemState)
+{
+ if (itemState & ODS_DISABLED)
+ return DFCS_INACTIVE;
+ else if (itemState & ODS_SELECTED)
+ return DFCS_PUSHED;
+ else if (itemState & ODS_HOTLIGHT)
+ return DFCS_HOT;
+ else
+ return 0;
+}
+
+void iupwinDrawButtonBorder(HWND hWnd, HDC hDC, RECT *rect, UINT itemState)
+{
+ if (!winDrawThemeButtonBorder(hWnd, hDC, rect, itemState))
+ {
+ DrawFrameControl(hDC, rect, DFC_BUTTON, DFCS_BUTTONPUSH | winDrawGetStateId(itemState));
+ if (itemState & ODS_DEFAULT) /* if a button has the focus, must draw the default button frame */
+ FrameRect(hDC, rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
+ }
+}
+
+void iupdrvDrawFocusRect(Ihandle* ih, void* gc, int x, int y, int w, int h)
+{
+ HDC hDC = (HDC)gc;
+ RECT rect;
+ (void)ih;
+
+ rect.left = x;
+ rect.top = y;
+ rect.right = x+w;
+ rect.bottom = y+h;
+
+ DrawFocusRect(hDC, &rect);
+}
+
+void iupwinDrawRemoveTheme(HWND hwnd)
+{
+ typedef HRESULT (STDAPICALLTYPE *winSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+ static winSetWindowTheme mySetWindowTheme = NULL;
+ if (!mySetWindowTheme)
+ {
+ HMODULE hinstDll = LoadLibrary("uxtheme.dll");
+ if (hinstDll)
+ mySetWindowTheme = (winSetWindowTheme)GetProcAddress(hinstDll, "SetWindowTheme");
+ }
+
+ if (mySetWindowTheme)
+ mySetWindowTheme(hwnd, L"", L"");
+}
+
+void iupwinDrawParentBackground(Ihandle* ih, HDC hDC, RECT* rect)
+{
+ unsigned char r=0, g=0, b=0;
+ char* color = iupBaseNativeParentGetBgColorAttrib(ih);
+ iupStrToRGB(color, &r, &g, &b);
+ SetDCBrushColor(hDC, RGB(r,g,b));
+ FillRect(hDC, rect, (HBRUSH)GetStockObject(DC_BRUSH));
+}
+
+HDC iupwinDrawCreateBitmapDC(iupwinBitmapDC *bmpDC, HDC hDC, int w, int h)
+{
+ bmpDC->w = w;
+ bmpDC->h = h;
+ bmpDC->hDC = hDC;
+
+ bmpDC->hBitmap = CreateCompatibleBitmap(bmpDC->hDC, w, h);
+ bmpDC->hBitmapDC = CreateCompatibleDC(bmpDC->hDC);
+ bmpDC->hOldBitmap = SelectObject(bmpDC->hBitmapDC, bmpDC->hBitmap);
+ return bmpDC->hBitmapDC;
+}
+
+void iupwinDrawDestroyBitmapDC(iupwinBitmapDC *bmpDC)
+{
+ BitBlt(bmpDC->hDC, 0, 0, bmpDC->w, bmpDC->h, bmpDC->hBitmapDC, 0, 0, SRCCOPY);
+ SelectObject(bmpDC->hBitmapDC, bmpDC->hOldBitmap);
+ DeleteObject(bmpDC->hBitmap);
+ DeleteDC(bmpDC->hBitmapDC);
+}
+