我正在使用BCB6,但它应该与Delphi相同,如果我只是在我的表单中添加这样的处理程序:
void __fastcall TForm1::WndProc(TMessage &Message)
Run Code Online (Sandbox Code Playgroud)
并处理WM_PAINT,我没有得到TWinControl提供的DoubleBuffered的好处.有没有办法在表单上做一些自定义绘画,尊重DoubleBuffered设置(也就是写入TWinControl创建的内存位图)?
controls.pas中的此函数是DoubleBuffered应用的位置:
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
Run Code Online (Sandbox Code Playgroud)
它创建一个内存位图,然后再次调用自身.所以当Message.DC为0时我需要一种方法来调用该函数,所以它会创建位图然后我不会再调用它...但是WMPaint不是虚拟的,也不是PaintHandler,所以我我没有看到一种方法来吸引这个.
我知道我可以创建自己的双缓冲,但如果可能的话,我宁愿使用已经存在的东西.我计划将这个设计转移到其他控件上,而不仅仅是我的表格.
我正在使用此代码捕获屏幕:
public Bitmap CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the …Run Code Online (Sandbox Code Playgroud) 我想我必须遗漏一些明显的东西,但经过几个小时的搜索后我无法找到它.是否无法使用PictureBox或其他控件来包含具有部分透明/ alpha混合像素的图像,并将其放在另一个图像上并使混合基于其下的图像?
例如,这会产生我想要的结果:
这不是:
将PictureBox放在窗体上并将其设置为PNG.
将另一个PictureBox放在窗体上并将其设置为PNG.
将第二个图片框放在第一个图片框上.
...即使第二个图片框只是空的并且背景颜色为透明,它仍然覆盖下面的图片.
我已经读过这个源于所有winform控件的窗口,因此本质上它们并不透明.
...但即使是我正在迁移的15年历史的平台,Borland的VCL也有几个没有窗口的控件,因此很难成像winforms并不至少有一些简单的解决方案?
我上面的第一个例子是一个答案,是的,但是当你只能使用一个大面板并在其中绘制所有"控件"时,这会增加许多工作.如果您可以使用单独的鼠标事件/等单独控件,那就更好了.即使不是图像控制,也是我必须自己绘制的控件,只要我可以在每个控件中放置一个图像,那就没问题了.在VCL中,他们称之为"油漆盒",只是一个矩形区域,您可以放置在一个表格上,并在其上绘制任何您想要的东西.它有自己的鼠标事件,界限等.如果你没有画任何东西,它就像它甚至没有(100%透明),除了它仍然得到鼠标事件,所以可以用作"热"现场"或"目标"也是如此.
我试图将一些C代码转换为Java,但它的工作方式略有不同.它是XOR加密,对于某些数据,它返回相同的结果,所以我知道它非常接近,但对于某些数据,它不能完全相同(不同的结果).
C代码(在x86 Windows上运行,使用Borland Builder编译):
void Crypt(unsigned char *data,long len)
{
char key[] = "X02$B:";
ULONG crypt_ptr;
long x;
for(crypt_ptr=0,x=0;x<len;x++)
{
data[x] ^= key[crypt_ptr];
if(crypt_ptr < (sizeof(key) - 2))
key[crypt_ptr] += key[crypt_ptr + 1];
else
key[crypt_ptr] += key[0];
if(!key[crypt_ptr])
key[crypt_ptr] += (char) 1;
if(++crypt_ptr >= sizeof(key) - 1)
crypt_ptr = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
Java代码(如果重要的话,它在Android平台上运行):
public static void Crypt(byte[] data,int offset,int len)
{
// EDIT: Changing this to byte[] instead of char[] seems to have fixed code
//char[] key = {'X','0','2','$','B',':'};
byte[] …Run Code Online (Sandbox Code Playgroud) 以下代码在显示表单之前(透明地)在屏幕上产生黑色闪烁,我想知道我有哪些选项可以消除该闪烁?
Form f = new Form();
f.BackColor = Color.Lime;
f.TransparencyKey = f.BackColor;
f.StartPosition = FormStartPosition.Manual;
f.Bounds = Screen.PrimaryScreen.WorkingArea;
f.Show();
Run Code Online (Sandbox Code Playgroud)
如果我创建一个新项目,将表单的背景设置为 Lime,将 TransparencyKey 设置为 Lime,然后单击运行,我会得到相同的结果。
我尝试过的事情:
将不透明度设置为 99%——同样的闪烁
在 OnCreateParams 中强制 WS_EX_COMPOSITED 或使用 SetWindowLong -- 同样闪烁
将窗口显示得更小,或 0 宽度,或关闭屏幕,然后移动到所需位置 - 导致显示错误,我的窗体后面的窗口无法正确重绘。
设置 ControlStyles.Opaque、ControlStyles.UserPaint 和其他几个 ControlStyles 组合并覆盖不同的绘画/背景绘画事件——各种结果,要么相同的闪烁,要么更糟的闪烁,要么形式不透明。
转向 WPF 可能是一种选择,但并不是真正寻找“使用 WPF”作为答案。