Witam.
Na formie całej "ze szkła", co jakiś określony czas (np co sekundę) rysuję kilka-kilkanaście napisów (zawsze w tym samym miejscu, zmienia się po prostu tylko tekst). Problem w tym, że po pewnym czasie działania programu użycie procesora ciągle wzrasta, aż w końcu aplikacja przestaje działać. Problem zapewne tkwi w zwalnianiu zasobów... Tylko jak to zrobić w tym wypadku? Jestem kompletnie zielony w temacie rysowania (zwłaszcza na szkle), a klasę Glass
znalazłem w sieci i nie wiem dokładnie jak działa metoda DrawTextOnGlass
dlatego proszę o jakiekolwiek wskazówki.
Kod mojej formy wygląda w uproszczeniu tak:
Random rnd = new Random();
public frmMain()
{
InitializeComponent();
BackColor = Color.Black;
Glass.MARGINS m = new Glass.MARGINS(-1, -1, -1, -1);
Glass.DwmExtendFrameIntoClientArea(this.Handle, ref m);
}
void timerDraw_Tick(object sender, EventArgs e)
{
int y = 0;
for (int i = 0; i < 15; i++)
{
int r = rnd.Next(0, 999); // tekstem niech będzie np. jakaś losowa liczba
Glass.DrawTextOnGlass(this.Handle, r.ToString(), this.Font, new Rectangle(5, y, 40, 15), 10);
y += 35;
}
}
A tak wygląda istotna część klasy Glass
:
[DllImport("gdi32.dll")]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true)]
private static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true)]
private static extern IntPtr CreateDIBSection(IntPtr hdc, ref BITMAPINFO pbmi, uint iUsage, int ppvBits, IntPtr hSection, uint dwOffset);
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true)]
private static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true)]
private static extern bool DeleteObject(IntPtr hObject);
[DllImport("UxTheme.dll", SetLastError = true, ExactSpelling = true)]
private static extern int DrawThemeText(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, string text, int iCharCount, int dwFlags1, int dwFlags2, ref RECT pRect);
[DllImport("UxTheme.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
private static extern int DrawThemeTextEx(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, string text, int iCharCount, int dwFlags, ref RECT pRect, ref DTTOPTS pOptions);
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableComposition(bool bEnable);
[DllImport("dwmapi.dll")]
internal static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);
[DllImport("dwmapi.dll")]
internal static extern void DwmIsCompositionEnabled(ref bool isEnabled);
public static void DrawTextOnGlass(IntPtr hwnd, string text, Font font, Rectangle ctlrct, int iglowSize)
{
if (IsCompositionEnabled())
{
RECT rect = new RECT();
RECT pRect = new RECT();
rect.left = ctlrct.Left;
rect.right = ctlrct.Right + (2 * iglowSize);
rect.top = ctlrct.Top;
rect.bottom = ctlrct.Bottom + (2 * iglowSize);
pRect.left = 0;
pRect.top = 0;
pRect.right = rect.right - rect.left;
pRect.bottom = rect.bottom - rect.top;
IntPtr dC = GetDC(hwnd);
IntPtr hdc = CreateCompatibleDC(dC);
IntPtr zero = IntPtr.Zero;
int dwFlags = 0x825;
BITMAPINFO pbmi = new BITMAPINFO();
pbmi.bmiHeader.biHeight = -(rect.bottom - rect.top);
pbmi.bmiHeader.biWidth = rect.right - rect.left;
pbmi.bmiHeader.biPlanes = 1;
pbmi.bmiHeader.biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
pbmi.bmiHeader.biBitCount = 0x20;
pbmi.bmiHeader.biCompression = 0;
if (SaveDC(hdc) != 0)
{
IntPtr hObject = CreateDIBSection(hdc, ref pbmi, 0, 0, IntPtr.Zero, 0);
if (hObject != IntPtr.Zero)
{
zero = SelectObject(hdc, hObject);
IntPtr ptr6 = font.ToHfont();
IntPtr ptr5 = SelectObject(hdc, ptr6);
try
{
VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.Window.Caption.Active);
DTTOPTS pOptions = new DTTOPTS();
pOptions.dwSize = (uint)Marshal.SizeOf(typeof(DTTOPTS));
pOptions.dwFlags = 0x2800;
pOptions.iGlowSize = iglowSize;
DrawThemeTextEx(renderer.Handle, hdc, 0, 0, text, -1, dwFlags, ref pRect, ref pOptions);
BitBlt(dC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdc, 0, 0, 0xcc0020);
}
catch (Exception exception)
{
Trace.WriteLine(exception.Message);
}
SelectObject(hdc, zero);
SelectObject(hdc, ptr5);
DeleteObject(hObject);
DeleteObject(ptr6);
ReleaseDC(hdc, -1);
DeleteDC(hdc);
}
}
}
}