如何在windows窗口客户区内的指定区域内绘制图形?

灼眼的超哥 2013-02-17 09:13:41
如题,已知区域的坐标(x,y)及尺寸(w,h),假设保存像素数据的数组是 rgb_pixel_data, 图形宽为 w, 图形高为 h,图形要显示在客户区内的(x, y)坐标处。
该如何将自己的数据写到客户区内,以使客户区内显示相应图形?


//省略其它代码
int x, y, w, h;
unsigned char *rgb_pixel_data;

//省略其它代码

case WM_PAINT:
BeginPaint (hwnd, &ps);
x = ps.rcPaint.left;
y = ps.rcPaint.top;
w = ps.rcPaint.right - area.x;
h = ps.rcPaint.bottom - area.y;
//此处添加代码,以对客户区内的指定区域内绘制图形
EndPaint (hwnd, &ps);
return 0;

//省略其它代码
...全文
460 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
灼眼的超哥 2013-02-18
  • 打赏
  • 举报
回复
引用 3 楼 sha_jinhao 的回复:
对 用strechblt可以使图形按照窗口的大小来显示 bitblt不具备这样的功能!
请看上述代码,我想将一个图形绘制到客户区内指定位置上。 之前试过FillRect,但它只能指定区域内填充单一颜色,而我现在想在指定区域内绘制自定义图形。
jimette 2013-02-18
  • 打赏
  • 举报
回复
对 用strechblt可以使图形按照窗口的大小来显示 bitblt不具备这样的功能!
灼眼的超哥 2013-02-18
  • 打赏
  • 举报
回复
引用 1 楼 sha_jinhao 的回复:
strechblt
StrechBlt?我用的是BitBlt. 还是贴测试代码吧:

#include <stdio.h>
#include <fcntl.h>
#include <windows.h>

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 480

typedef struct _MYArea {
	int x, y, w, h;
}MYArea;

static void Win32_GetClientBitmap( HBITMAP area_bitmap, MYArea area )
{
	unsigned char *pixel_mem;
	pixel_mem = malloc (area.w*area.h*3);
	/* 像素数据全部填充为RGB(150,150,150) */
	memset (pixel_mem, 150, area.w*area.h*3);
	/* 设定位图数据 */
	SetBitmapBits (area_bitmap, area.w*area.h*3, pixel_mem);
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	HDC hdcClient,hdcArea;
	PAINTSTRUCT ps;
	HBITMAP area_bitmap;
	MYArea area;
	
	switch (message){
	case WM_KEYDOWN:
		printf("WM_KEYDOWN: %ld\n",lParam);
	case WM_LBUTTONDOWN:
		//PostEBMessage(mainApp.desktop.handle,EB_LBUTTONDOWN,wParam,lParam);
		break;
	case WM_MOUSEMOVE:
		//PostEBMessage(mainApp.desktop.handle,EB_MOUSEMOVE,wParam,lParam);
		break;
	case WM_LBUTTONUP:
		//PostEBMessage(mainApp.desktop.handle,EB_LBUTTONUP,wParam,lParam);
		break;
	case WM_PAINT:
		BeginPaint (hwnd, &ps);
		/* 获取区域坐标及尺寸 */
		area.x = ps.rcPaint.left;
		area.y = ps.rcPaint.top;
		area.w = ps.rcPaint.right - area.x;
		area.h = ps.rcPaint.bottom - area.y;
		hdcClient = GetDC (hwnd);
		/* 为区域创建一个DC */
		hdcArea = CreateCompatibleDC (hdcClient);
		/* 为区域创建一个位图 */ 
		area_bitmap = CreateCompatibleBitmap (hdcArea, area.w, area.h);
		/* 获取该区域内显示的图形数据 */
		Win32_GetClientBitmap (area_bitmap, area);
		/* 替换区域内显示的图形数据 */
		SelectObject (hdcArea, area_bitmap);
		/* 将区域内的图形更新至客户区内 */
		BitBlt (hdcClient, area.x, area.y, area.w, area.h, hdcArea, 0, 0, SRCCOPY ); 
		
		printf("area:%d,%d,%d,%d\n", area.x, area.y, area.w, area.h);
		
		DeleteDC (hdcArea);
		ReleaseDC (hwnd, hdcClient);
		EndPaint (hwnd, &ps);
		return 0;
		break;
	case WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

/* 在运行程序时会打开控制台,以查看打印的调试信息 */
void InitConsoleWindow(void)
{
	int hCrt;
	FILE *hf;
	AllocConsole();
	hCrt=_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT );
	hf=_fdopen( hCrt, "w" );
	*stdout=*hf;
	setvbuf (stdout, NULL, _IONBF, 0);
	// test code
	printf ("InitConsoleWindow OK!\n");
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
	HWND		hwnd;
	MSG		msg;
	WNDCLASS	wndclass;
	static TCHAR	szAppName[] = TEXT ("Typer") ;
	
	InitConsoleWindow();
	
	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc   = WndProc ;
	wndclass.cbClsExtra    = 0 ;
	wndclass.cbWndExtra    = 0 ;
	wndclass.hInstance     = hInstance ;
	wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName  = NULL ;
	wndclass.lpszClassName = szAppName ;

	
	if (!RegisterClass (&wndclass)) {
		MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
		szAppName, MB_ICONERROR) ;
		return 0 ;
	}
	
	hwnd = CreateWindow (
			szAppName, 
			TEXT ("test"),
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, CW_USEDEFAULT,
			800, 600,
			NULL, NULL, hInstance, NULL);

	ShowWindow (hwnd, iCmdShow);
	UpdateWindow (hwnd);
	
	while (GetMessage (&msg, NULL, 0, 0)) {
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}
以上代码是参考其他示例代码修改而成,还存在一些问题。
zicerock123 2013-02-18
  • 打赏
  • 举报
回复
BitBlt,图像小于显示区会有出现背景色啊,除非你又画了背景。用strechblt吧,放大缩小都可以。
灼眼的超哥 2013-02-18
  • 打赏
  • 举报
回复
引用 5 楼 tiger9991 的回复:
FillRect只能绘制Rect带一种颜色的巨型。 GDI和GDI+的图形接口还是比较丰富的。不知道楼主要画的是哪种图形, ellipse 椭圆 MoveTo LineTo 画线 Polygon 多边形(三角)
还是叫“图像”好些,叫“图形”话,感觉是在绘制简单的直线、曲线、矩形什么的。 我搞了个具备简单的图像处理的函数库,调用该库里的函数可以将处理后的图像写入至图片文件。 但现在我想将图像显示在窗口客户区内,而不是写到图片文件里。 不知道如何将自定义的图像数据转为BITMAP,并让它显示在客户区内。
灼眼的超哥 2013-02-18
  • 打赏
  • 举报
回复
引用 5 楼 tiger9991 的回复:
FillRect只能绘制Rect带一种颜色的巨型。 GDI和GDI+的图形接口还是比较丰富的。不知道楼主要画的是哪种图形, ellipse 椭圆 MoveTo LineTo 画线 Polygon 多边形(三角)
自定义的,就是用自己的函数读图片,用自定义的结构体保存图片信息及像素数据。 或者是用自定义函数绘制的图形,图形信息及像素数据保存在自定义的结构体中。 不知如何将自定义的图形数据,绘制到windows的窗口客户区内。
lgstudyvc 2013-02-18
  • 打赏
  • 举报
回复
贴图就可以了,以前给客户在指定的区域显示不同大小的logo用过
看不见的裂痕 2013-02-18
  • 打赏
  • 举报
回复
FillRect只能绘制Rect带一种颜色的巨型。
GDI和GDI+的图形接口还是比较丰富的。不知道楼主要画的是哪种图形,
ellipse 椭圆
MoveTo LineTo 画线
Polygon 多边形(三角)
jimette 2013-02-17
  • 打赏
  • 举报
回复
strechblt

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧