问题描述
你好,
该问题与Windows GDI有关,实际上与重新绘制框架"区域有关(使用"FrameRgn"函数框架的HRGN)
寻找有关如何正确处理区域重绘的帮助或建议.
我创建了以下课程:
Hello,
The issue is related to Windows GDI, actually about repainting "framed" regions (HRGN framed with "FrameRgn" function)
Looking for help or an advice on how to handle regions repainting correctly.
I have created following class:
//*****************************************************
#ifndef OwnerDrawnButtonH
#define OwnerDrawnButtonH
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <jpeg.hpp>
#include <Graphics.hpp>
#include <windows.h>
//--------------------------------------------------------------------------
class
TOwnerDrawnButton {
HRGN rgn;
HWND hWnd;
TImage *img;
TForm *form;
COLORREF rgb;
public:
TOwnerDrawnButton (TForm *, TImage *, HWND);
TOwnerDrawnButton () {};
void __fastcall drawPressed();
void __fastcall drawFocused();
void __fastcall clearFrame();
};
#endif
//*****************************************************
一些方法的实现:
Implementation of some methods:
//*****************************************************
// constructor initializes "img" property with submited image parameter
// handle is HWND handle to forms window
TOwnerDrawnButton::TOwnerDrawnButton (TForm *frm, TImage *image, HWND handle)
{
rgb = 0x00ffeeff; // light gray RGB color code
hWnd = handle;
form = frm;
img = image;
}
//---------------------------------------------------------------
// "clearFrame" method draws two frames(outer, blue, 1 pixel width, and inner, gray, 4 pixels width) around region
// that corresponds to area under the "img" property of object
void __fastcall TOwnerDrawnButton::clearFrame()
{
// drawing outer frame, width 1 pixel
rgb = 0x00ff0000; // blue color RGB code
rgn = CreateRoundRectRgn(form->Left + img->Left + 1,
form->Top + 26 + img->Top + 1,
form->Left + img->Left + img->Width + 12,
form->Top + 26 + img->Top + img->Height + 12,
4 , 4);
HDC hdc = GetDC(hWnd);
HBRUSH brush = CreateSolidBrush(rgb);
FrameRgn(hdc, rgn, brush, 1, 1);
ReleaseDC(hWnd,hdc);
DeleteObject(rgn);
// drawing inner frame, width 4 pixels
rgb = 0x00ffeeff; // light gray RGB color code
rgn = CreateRoundRectRgn(form->Left + img->Left + 2,
form->Top + 26 + img->Top + 2,
form->Left + img->Left + img->Width + 11,
form->Top + 26 + img->Top + img->Height + 11,
4 , 4);
hdc = GetDC(hWnd);
brush = CreateSolidBrush(rgb);
FrameRgn(hdc, rgn, brush, 4, 4);
ReleaseDC(hWnd,hdc);
DeleteObject(rgn);
}
//*****************************************************
我在窗体上放置了两个位图图像(通过从工具栏拖动图像"图标-TImage * img1,TImage * img2).然后,我将位图图像加载到其图片属性(TBitmap *-类型)上.在表单的私有部分中,我声明了两个属性,类型为TOwnerDrawnButton *:TOwnerDrawnButton *odButton1;
TOwnerDrawnButton *odButton2;
现在,在表单构造函数中,我已经以下面的方式初始化了这两个TOwnerDrawnButton对象:odButton1 = new TOwnerDrawnButton(this, img1, hwnd);
I put two bitmap images on the form (by dragging Image icon from toolbar - TImage *img1, TImage *img2). Then i load bitmap images on to their Picture properties (TBitmap * - type). In the private section of the form i have declared two attributes type TOwnerDrawnButton*:TOwnerDrawnButton *odButton1;
TOwnerDrawnButton *odButton2;
Now, in the forms constructor I have initialized these two TOwnerDrawnButton objects next way :odButton1 = new TOwnerDrawnButton(this, img1, hwnd);
odButton2 = new TOwnerDrawnButton(this, img2, hwnd);<br />
为了始终在窗体上的图像周围绘制框架,我将以下代码放在窗体的OnPaint事件中:odButton1->clearFrame();
odButton2->clearFrame();
当我运行应用程序时,问题在于,当我的窗体窗口不是最顶部时(我将其他打开的窗口拖动到其上方),这些区域框架被重新绘制在前景窗口的顶部.我了解这是正常的,因为发生了OnPaint事件中的代码,但是不知道解决这种情况的方法.
更多信息:
我正在使用Borland C ++ Builder(包括VCL库)(使用拖放"技术创建表单)在C ++中进行编码.实际上,我创建了表单(目前,它只是开始新项目时最初创建的第一个表单),并在上面放置了两个图像组件(VCL库,Additional Tab,将图像组件拖放到表单上). >
这样,我添加了两个"TImage *"类型的IDE托管组件(分别为img1和img2):
TImage* img1;
TImage* img2;
每个"TImage *"对象/组件都有自己的Picture属性,该属性属于TBitmap类型.因此,在对象检查器中,我已为图片"属性分配了适当的位图图像.
感谢任何帮助或建议.
To always have painted frames around images on the form, i put following code in an OnPaint event of the form:odButton1->clearFrame();
odButton2->clearFrame();
When i run application, problem is that when my forms window is not top most (i drag some other opened window above it), those region frames are being redrawed on top of the foreground window. I understand that it is normal because of the code in an OnPaint event, but don''t know the way to solve this situation.
Some more information:
i am coding in C++ using Borland C++ Builder, including VCL library (creating forms with ''drag and drop'' technique). Actually, I created form (for now it''s just that first form initially created when you start new project) and put two image components on it (VCL library, Additional Tab, dragged and dropped Image component on form).
This way i added two IDE Managed Components of ''TImage *'' type (named img1 and img2):
TImage* img1;
TImage* img2;
Each ''TImage*'' object/component has its own Picture property, which is of TBitmap type. So, in Object Inspector i have assigned proper bitmap images to Picture properties.
Appreciate any help or advice.
推荐答案
void __fastcall TOwnerDrawnButton::clearFrame()
{
form->Canvas->Pen->Style = psSolid;
form->Canvas->Pen->Width = 4;
form->Canvas->Pen->Color = clLtGray;
form->Canvas->Brush->Style = bsClear;
form->Canvas->Rectangle(
img->Left - 2,
img->Top - 2,
img->Left + img->Width + 2,
img->Top + img->Height + 2
);
}
这样,它直接在Forms Canvas上绘制,与使用区域和画笔相比,它需要较少的内存管理(分配和释放).
为了能够直接在表单上绘制,必须将FormStyle
设置为fsNormal
或fsStayOnTop
.
This way it draws directly on forms canvas, and requires less memory management (allocating and freeing) comparing to using regions and brushes.
To be able to draw directly on a form, FormStyle
must be set either to fsNormal
or fsStayOnTop
.
这篇关于Windows图形问题,HRGN区域重绘问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!