小编ese*_*elk的帖子

Delphi/Builder/VCL,覆盖形式的WM_PAINT而不会丢失双缓冲?

我正在使用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,所以我我没有看到一种方法来吸引这个.

我知道我可以创建自己的双缓冲,但如果可能的话,我宁愿使用已经存在的东西.我计划将这个设计转移到其他控件上,而不仅仅是我的表格.

delphi vcl builder

2
推荐指数
1
解决办法
1424
查看次数

C#捕获屏幕为8位(256色)位图

我正在使用此代码捕获屏幕:

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)

.net c# graphics bitmap screen-capture

2
推荐指数
1
解决办法
4129
查看次数

在半透明PNG上形成半透明PNG

我想我必须遗漏一些明显的东西,但经过几个小时的搜索后我无法找到它.是否无法使用PictureBox或其他控件来包含具有部分透明/ alpha混合像素的图像,并将其放在另一个图像上并使混合基于其下的图像?

例如,这会产生我想要的结果:

  1. 在表单上放置一个面板.
  2. 添加OnPaint处理程序.
  3. 在OnPaint处理程序中绘制1个PNG,然后在其上绘制另一个PNG,使用Graphics.DrawImage.

这不是:

  1. 将PictureBox放在窗体上并将其设置为PNG.

  2. 将另一个PictureBox放在窗体上并将其设置为PNG.

  3. 将第二个图片框放在第一个图片框上.

...即使第二个图片框只是空的并且背景颜色为透明,它仍然覆盖下面的图片.

我已经读过这个源于所有winform控件的窗口,因此本质上它们并不透明.

...但即使是我正在迁移的15年历史的平台,Borland的VCL也有几个没有窗口的控件,因此很难成像winforms并不至少有一些简单的解决方案?

我上面的第一个例子是一个答案,是的,但是当你只能使用一个大面板并在其中绘制所有"控件"时,这会增加许多工作.如果您可以使用单独的鼠标事件/等单独控件,那就更好了.即使不是图像控制,也是我必须自己绘制的控件,只要我可以在每个控件中放置一个图像,那就没问题了.在VCL中,他们称之为"油漆盒",只是一个矩形区域,您可以放置​​在一个表格上,并在其上绘制任何您想要的东西.它有自己的鼠标事件,界限等.如果你没有画任何东西,它就像它甚至没有(100%透明),除了它仍然得到鼠标事件,所以可以用作"热"现场"或"目标"也是如此.

user-interface png transparency winforms

2
推荐指数
1
解决办法
4534
查看次数

这个Java和C代码之间的区别?

我试图将一些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)

c java encryption xor

1
推荐指数
1
解决办法
261
查看次数

使用 TransparencyKey 设置首次显示 Winform 时消除黑色闪烁

以下代码在显示表单之前(透明地)在屏幕上产生黑色闪烁,我想知道我有哪些选项可以消除该闪烁?

   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,然后单击运行,我会得到相同的结果。

我尝试过的事情:

  1. 将不透明度设置为 99%——同样的闪烁

  2. 在 OnCreateParams 中强制 WS_EX_COMPOSITED 或使用 SetWindowLong -- 同样闪烁

  3. 将窗口显示得更小,或 0 宽度,或关闭屏幕,然后移动到所需位置 - 导致显示错误,我的窗体后面的窗口无法正确重绘。

  4. 设置 ControlStyles.Opaque、ControlStyles.UserPaint 和其他几个 ControlStyles 组合并覆盖不同的绘画/背景绘画事件——各种结果,要么相同的闪烁,要么更糟的闪烁,要么形式不透明。

转向 WPF 可能是一种选择,但并不是真正寻找“使用 WPF”作为答案。

transparency flicker winforms

1
推荐指数
1
解决办法
1436
查看次数