private void SetupWindow() { Debug.WriteLine(DateTime.Now + ": Setting up window."); // get the windows graphics object Graphics GFX = Graphics.FromHwnd(IntPtr.Zero); SizeF TextRect; // measure the size of the string based on the maximum width TextRect = GFX.MeasureString(m_Text, m_Font, m_MaxWidth, StringFormat.GenericTypographic); // create the new client rectangle based on the size of the text rectangle, then inflate it by the padding m_ClientRectangle = new Rectangle(0, 0, (int)TextRect.Width + 1, (int)TextRect.Height + 1); m_ClientRectangle.Inflate(PADDING, PADDING); // if the window handle is not null if (m_ToolTipWnd.Handle != IntPtr.Zero) { // if we are using uxthemes if (m_Style == ToolStyle.UxTheme) { // grab the theme and graphics handle IntPtr pTheme = GetToolTipTheme(); IntPtr hdc = GFX.GetHdc(); // if the pointer is not null if (pTheme != IntPtr.Zero) { // create a RECT to pass to the theme routine and create a region pointer RECT ClipRect = new RECT(0, 0, m_ClientRectangle.Width, m_ClientRectangle.Height); IntPtr pRegion = IntPtr.Zero; // attempt to get the region of the theme if (ThemeRoutines.GetThemeBackgroundRegion(pTheme, hdc, (int)ToolTipPart.Standard, (int)ToolTipStandardState.TTSS_NORMAL, ref ClipRect, out pRegion) == 0) { // if we were successful, go ahead and set the window region, this will give us rounded edges Win32.SetWindowRgn(m_ToolTipWnd.Handle, pRegion, true); // TODO: Determine if not releasing the region object pointed to will cause memory leaks (likely use deleteobject) } else { // otherwise, fall to the failsafe, assume the entire rectangle is visible, set that as the region Win32.SetWindowRgn(m_ToolTipWnd.Handle, ref ClipRect, true); } } // release the hdc GFX.ReleaseHdc(hdc); } } // dispose the graphics object GFX.Dispose(); }
private void PaintToolTip(ref Message msg) { try { // get the open them and graphics object Debug.WriteLine(DateTime.Now + ": Painting Tooltip."); Graphics GFX = Graphics.FromHwnd(m_ToolTipWnd.Handle); IntPtr pTheme = GetToolTipTheme(); // if we are using uxtheme and have an open theme available if (m_Style == ToolStyle.UxTheme && pTheme != IntPtr.Zero) { // get the clip rectangle from the client rectangle RECT ClipRect = new RECT(0, 0, m_ClientRectangle.Width, m_ClientRectangle.Height); IntPtr hdc = GFX.GetHdc(); //DrawingUtils.GDI.GDI.SetBkMode(hdc, 1); // draw the themed background using uxtheme ThemeRoutines.DrawThemeBackground(pTheme, hdc, (int)ToolTipPart.Standard, (int)ToolTipStandardState.TTSS_NORMAL, ref ClipRect, ref ClipRect); // TODO: Draw the themed text as well GFX.ReleaseHdc(hdc); } else { // otherwise, this is for flat style and fail safe // get a pen with the border color and clear the background using the backcolor Pen brderPen = new Pen(m_BorderColor, BORDERWIDTH); GFX.Clear(m_BackColor); // draw the border and dispose the pen GFX.DrawRectangle(brderPen, 0, 0, m_ClientRectangle.Width - BORDERWIDTH, m_ClientRectangle.Height - BORDERWIDTH); brderPen.Dispose(); } // get the text bounds by using the client rectangle and deflating it by the padding width Rectangle TxtBounds = new Rectangle(-1, -1, m_ClientRectangle.Width, m_ClientRectangle.Height); TxtBounds.Inflate(-PADDING, -PADDING); // get a new brush using the forecolor and draw the string Brush bshFrgrnd = new SolidBrush(m_ForeColor); GFX.DrawString(m_Text, m_Font, bshFrgrnd, TxtBounds); // clean up what we used bshFrgrnd.Dispose(); GFX.Dispose(); // return the hresult of zero and validate the entire rectangle msg.Result = IntPtr.Zero; Win32.ValidateRect(msg.HWnd, IntPtr.Zero); } catch (Exception ex) { Debug.WriteLine(ex.Message); } }