标签: device-context

了解设备上下文

作为MFC的相对新手,我看到了很多设备上下文(DC).我隐约明白它与绘图有关,但具体内容在我能找到的任何地方都没有得到很好的解释.创建"兼容的设备上下文"是什么意思,为什么它很重要?SelectObject做了什么,我该如何首先兼容DC?

mfc device-context

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

没有打电话给ReleaseDC会发生什么坏事?

一旦我们通过GetDC获得上下文设备使用C++编程.如果我们在不调用ReleaseDC的情况下退出程序,可能会发生什么不好的事情?

c++ opengl graphics winapi device-context

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

CreateCompatibleDC出现奇怪错误

也许这是一个愚蠢的问题,我不明白为什么我不能在以下代码中创建DC:

HBITMAP COcrDlg::LoadClippedBitmap(LPCTSTR pathName,UINT maxWidth,UINT maxHeight)
{
    HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, pathName, IMAGE_BITMAP, 0, 0,
                                  LR_LOADFROMFILE | LR_CREATEDIBSECTION);       
    if (!hBmp)
        return NULL;

    HDC hdc = (HDC)GetDC();
    HDC hdcMem = CreateCompatibleDC(hdc);
    if (!hdcMem)
    {
        DWORD err = GetLastError();
    }  
    ...
    ...
    ...
Run Code Online (Sandbox Code Playgroud)

位图hBmp加载正常,hdc具有有效值.但是对CreateCompatibleDC()的调用返回一个NULL指针.然后,GetLastError()返回0!有谁能猜出这里发生了什么,拜托?

PS:在此之前没有调用内存分配或GDI例程...所以我认为应该排除内存泄漏.

c++ windows mfc gdi device-context

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

Win32:窗口的整个生命周期内是否都有相同的HDC?

我可以在油漆循环外使用DC吗?我的窗户的DC是否保证永久有效?

我想弄清楚我的控件的设备上下文(DC)有效多长时间.

我知道我可以打电话:

GetDC(hWnd);
Run Code Online (Sandbox Code Playgroud)

获取我的控件窗口的设备上下文,但这是允许的吗?

当Windows向我发送WM_PAINT消息时,我应该调用BeginPaint/EndPaint来正确确认我已经绘制它,并在内部清除无效区域:

BeginPaint(hWnd, {out}paintStruct);
try
   //Do my painting
finally
   EndPaint(hWnd, paintStruct);
end;
Run Code Online (Sandbox Code Playgroud)

但是调用BeginPaint也会在PAINTSTRUCT结构中返回一个DC.这是我应该画的DC .

我在文档中找不到任何说明BeginPaint()返回的DC与我从GetDC()获得的DC相同的内容.

特别是现在,在桌面组合的时代,我在BeginPaint之外获得的DC上绘画是否有效?

在涂装周期中,似乎有两种方法可以让DC涂漆:

  1. dc = GetDC(hWnd);

  2. 调用BeginPaint(&PAINTSTRUCT);

还有第三种方法,但它似乎是我开发的Borland Delphi的一个错误.

WM_PAINT处理期间,Delphi认为wParam是一个DC,并继续绘制它.而MSDN表示WM_PAINT消息的wParam未使用.

为什么

我的真正目标是尝试将持久的GDI + Graphics对象与HDC保持一致,这样我就可以使用一些更好的GDI +功能,这些功能依赖于持久性DC.

在WM_PAINT消息处理期间,我想将一个GDI +图像绘制到画布上.以下nieve版本非常慢:

WM_PAINT:
{
   PAINTSTRUCT ps;
   BeginPaint(m_hwnd, ps);
   Graphics g = new Graphics(ps.hdc);
   g.DrawImage(m_someBitmap, 0, 0);
   g.Destroy();
   EndPaint(h_hwnd, ps);
}
Run Code Online (Sandbox Code Playgroud)

GDI包含性能更快的位图,即CachedBitmap.但是不假思索地使用它不会带来任何性能优势

WM_PAINT:
{
   PAINTSTRUCT ps;
   BeginPaint(m_hwnd, ps);

   Graphics g = new Graphics(ps.hdc);
   CachedBitmap bm = new …
Run Code Online (Sandbox Code Playgroud)

windows gdi+ gdi paint device-context

5
推荐指数
2
解决办法
7046
查看次数

为什么自定义光标图像显示不正确?

背景

我编写了一个函数,它根据与给定设备上下文关联的位图创建自定义光标.我使用它来创建拖拽光标,显示为"撕下" - 有点像它们在"Trello"中使用.

我一直在使用该函数一段时间没有问题,但当我使用它与新的树组件我正在努力它开始创建部分空白游标.

我已经验证了Delphi 2010Delphi Berlin都出现了这个问题,并且我也验证了它在Windows 7Windows 10中都被破坏了.

这是一张显示光标应该是什么样子的照片(对不起 - 找不到快速浏览光标的方法):

在此输入图像描述

而且当它部分空白时它看起来像是什么(好吧,它不仅仅是部分空白 - 它实际上是不可见的):

在此输入图像描述

故障排除

在我发现故障排除之后,如果调用GetDragCursor 之前将PNG图像写入与DC关联的位图,则光标会混乱.

这是我能想到的最简单的代码,用于演示问题:

包含两个TPaintBox组件的表单:MyPaintBoxWorksMyPaintBoxBroken.

  • 当您单击MyPaintBoxWorks时,您将获得预期的光标.
  • 当您单击MyPaintBoxBroken时,您只需获取png图像.

为了使其易于阅读(我希望),我已经排除了所有错误和资源处理.这对问题没有影响.为了使其工作,您需要访问Png图像.任何png图像都可以.然后更新代码以加载图像.

uses
  Types,
  pngimage;

//////////////////////////////////////////////////////////////////////
procedure TMyForm.FormPaint(Sender: TObject);
begin
  MyPaintBoxWorks.Canvas.Brush.Color := clGreen;
  MyPaintBoxWorks.Canvas.Rectangle( 0, 0,
                                    MyPaintBoxWorks.Width, MyPaintBoxWorks.Height );
  MyPaintBoxBroken.Canvas.Brush.Color := clRed;
  MyPaintBoxBroken.Canvas.Rectangle( 0, 0,
                                     MyPaintBoxBroken.Width, MyPaintBoxBroken.Height );
end;

function GetDragCursor( Handle: HDC;
                        Width, Height: integer;
                        CursorX, CursorY: integer ): TCursor; forward; …
Run Code Online (Sandbox Code Playgroud)

windows delphi bitmap cursor device-context

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

Win32 DrawText行高

我正在调用Win32 DrawText函数将一些文本输出到设备上下文中.文本很长,很好地包装在第二行.问题是我需要减少线之间的空间(我猜减少线高?).关于如何做到这一点的任何想法?

我只会打DrawText两次电话(每一行一次)但是我必须做自己的自动换行.

还有其他方法吗?

谢谢

winapi text gdi device-context

4
推荐指数
2
解决办法
2717
查看次数

当我释放画布时,DC会发生什么?

在这段代码中,我希望有一个调用ReleaseDC发生MyCanvas.Free,但这段代码运行正常,怎么样?
TCanvas自己的DC会发生什么?

var GlobalDC: THandle;

procedure TForm1.FormCreate(Sender: TObject);
begin
   GlobalDC:= GetDC(0);
end;

function LoopMeOften(const X, Y: Integer): TColor;
var
  MyCanvas: TCanvas;
begin
  MyCanvas := TCanvas.Create;
  MyCanvas.Handle := GlobalDC;
  Result := GetPixel(MyCanvas.Handle, X, Y);
  MyCanvas.Free;
end;
Run Code Online (Sandbox Code Playgroud)

delphi canvas device-context

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

两个DC可以共享一个GDI对象(画笔,笔等)吗?

两个设备上下文(DC)可以共享一个GDI对象,例如画笔还是笔?

windows winapi gdi device-context

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

如何绘制圆角矩形而不填充它(在MFC中)?

另外一个绘图问题MFC/GDI大师那里...... :-)

我正在使用MFC,我正在使用CDC对象进行绘图.这很好.

但是现在我想绘制一个带圆角的矩形,这条线宽几个像素.但我不希望任何填充发生!有一种方法CDC :: RoundRect - 我只是设置了我想要的笔,并用这支笔得到一个漂亮的圆角矩形.但CDC :: RoundRect也用当前画笔填充矩形.

有没有办法画线,没有填充?我还没找到任何其他方法?或者我可以创建某种"空刷",它不会改变矩形中间的内容吗?

我非常感谢你的一些好建议!

/来自瑞典的安德斯

windows mfc drawrectangle device-context

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

如何创建每像素24位的内存DC?

我需要它使用GDI函数处理RGB24数据(特别是StretchBlt()非常快)我不能使用CreateCompatibleDC(),因为它只能用其他DC的颜色深度创建内存DC.通常它用于屏幕DC(通过传输NULL指针到功能),通常屏幕的颜色深度为32.此外我不能依赖它,'因为如果屏幕设置被更改,我的应用程序可能无法正常工作.

所以我需要一些方法来创建具有特定特定颜色深度的内存DC.到目前为止,我发现使用CreateDC()函数只有一种方法,但它需要许多特定于设备的参数,对我来说似乎有点不可靠.此外,有太多的字段需要填充适当的值来调用CreateDC().

是否有一些更简单的方法来创建特定的内存DC而不依赖于某些设备?或者即使创建24 bpp的内存DC?

PS我需要一些快速的图形.我已经尝试手动将alpha通道添加到位图以使用它兼容屏幕32bpp内存DC并且它已经解决了,但是太慢了.正如我上面所说,我不能依赖可以更改的屏幕设置.

c++ winapi gdi device-context

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

Win32:如何从DC获取窗口(与GetDC相反)

有没有办法让窗口处理窗口拥有win32 DC?或者任何其他可能对识别窗口有用的信息,如DC宽度和高度?

winapi gdi device-context

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

标签 统计

device-context ×11

gdi ×6

winapi ×5

windows ×5

c++ ×3

mfc ×3

delphi ×2

bitmap ×1

canvas ×1

cursor ×1

drawrectangle ×1

gdi+ ×1

graphics ×1

opengl ×1

paint ×1

text ×1