How to call DrawThemeTextEx in .NET

℡╲_俬逩灬. 提交于 2019-12-21 06:00:54

问题


I need to write a text with glow in a Vista/seven glass window, and I'm, trying to call the API to write some text there. I have checked out a great sample in CodeProject, but the problem is that I'm using .NET 1 (please, don't ask :-)

I need to translate the follwing .NET 2 code to PInvoke, .NET 1 code.

// using System.Windows.Forms.VisualStyles
VisualStyleRenderer renderer = new VisualStyleRenderer(
                               VisualStyleElement.Window.Caption.Active);

// call to UxTheme.dll
DrawThemeTextEx(renderer.Handle, 
                memoryHdc, 0, 0, text, -1, (int)flags,    
                ref textBounds, ref dttOpts);

The class VisualStyleRenderer does not exist in .NET 1, so I need to get the renderer.Handle in other way.


回答1:


Define the OpenThemeData API and DrawThemeTextEx, as well as some required structs and constants:

    [DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
    private static extern IntPtr OpenThemeData(IntPtr hwnd, string pszClassList);

    [DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
    private extern static Int32 DrawThemeTextEx(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, string pszText, int iCharCount, uint flags, ref RECT rect, ref DTTOPTS poptions);

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DTTOPTS
    {
      public int dwSize;
      public int dwFlags;
      public int crText;
      public int crBorder;
      public int crShadow;
      public int iTextShadowType;
      public int ptShadowOffsetX;
      public int ptShadowOffsetY;
      public int iBorderSize;
      public int iFontPropId;
      public int iColorPropId;
      public int iStateId;
      public bool fApplyOverlay;
      public int iGlowSize;
      public IntPtr pfnDrawTextCallback;
      public IntPtr lParam;
    }

    // taken from vsstyle.h
    private const int WP_CAPTION = 1;
    private const int CS_ACTIVE = 1;

And then, call it like this:

IntPtr handle = OpenThemeData(IntPtr.Zero, "WINDOW");
DrawThemeTextExt(handle, hdc, WS_CAPTION, CS_ACTIVE, ...)

The WS_CAPTION and CS_ACTIVE values match .NET 2's Caption and Active respectively. Values are described here officially: Parts and States




回答2:


In short, you get what you want by calling OpenThemeData().

To work out all the details it would be much easier for you to write a sample app in C++ to get to know how to drive the theme API from the ground up. There are many tutorials and lots of sample code on the web. But do it in C++ where you will have all the functions readily available. The last thing you want to get doing is fighting with P/Invokes whilst you are also getting to grips with low-level theme API.

Once you get it cracked in C++, then move on to the P/Invokes and if you have trouble it will be easy to refer back to the C++ code that works.



来源:https://stackoverflow.com/questions/5461937/how-to-call-drawthemetextex-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!