zoukankan      html  css  js  c++  java
  • windows程序设计第4章Text Output练习(831121)

    Painting和重绘

    通过Post WM_PAINT消息通知WndProc,客户区的无效区域要重绘。

    WM_PAINT消息

    在以下情况下WndProc收到WM_PAINT

    1.被遮挡的区域通过窗口移动又重现

    2..resize

    3. ScrollWindow或ScrollDC的调用,以scroll客户区

    4. 程序调用了InvalidateRect或InvalidateRgn

        有时,当客户区的某部分被暂时重写时,Windows也会试图保存之前的display以便restore。但不保证成功,所以有时Windows也会post WM_PAINT消息,有下列几种情况:

    1.对话框,消息框在客户区的移动

    2.menu拉动

    3.tool tip显示

    在下列情况,windows可以restore之前保存的display

    1.mouse光标移动

    2.icon拖曳入客户区

    Valid和Invalid矩形区

         每次只需更新一个小的区域,即有display更改的矩形区域,以提高绘制效率。当客户区有invalid区时,Windows就会将WM_PAINT消息放置到消息队列。

         Wndows内部对每个窗口都维护了一个paint information structure,对于invalid区,包含了一个最小的能encompass invalid区的矩形,即”invalid矩形”。倘若在WndProc处理等待的WM_PAINT消息之前,又有新的invalid区产生,则Windows会计算对应的新的invalid矩形。

         WndProc可以通过调用InvalidateRect函数,来使自己的客户区的一个矩形变成invalid矩形,倘若此时队列中有WM_PAINT,则合并生成新的invalid矩形,否则,则放置一个WM_PAINT到队列。

         通过GetUpdateRect,我们可得到invalid矩形的坐标。而通过调用ValidateRect函数,可将任一矩形区设为valid,如果该函数将整个客户区都validate了,那么队列中的WM_PAINT将统统被移去。(有invalid矩形,才有重绘的必要)。

    GDI介绍

        GDI(Graphics Device Interface)。

    设备上下文(DC)

        DC是GDI内部维护的一个数据结构,它和一个特定的显示设备联系在一起。DC有一些graphics的属性值,诸如文字颜色,字体等等。用完DC后,要记得release。

    获取DC句柄:法1

         在处理WM_PAINT时用此法,涉及两个函数,BeginPaint和EndPaint。使用前者填充PAINTSTRUCT结构ps,并返回DC句柄,后者负责释放DC。

    必须成对出现。另外,有一个很重要的clipping区的概念,windows只能在clipping区绘制,调用BeginPaint,将会把Update区设为clipping区,如果有标志要erase背景,则BeginPaint会将Update区的背景擦掉。BeginPaint还会把invalid区设为有效,不用担心,原来的invalid区信息已保存在DC和ps中。

    Paint信息结构

    fErase:是否要erase背景,如果之前调用了BeginPaint,则不需要,如果调用InvalidateRect,并将该函数的最后一个参数设为0,则引发的WM_PAINT处理时,fErase为真,需要erase invalid矩形的背景。

    rcPaint: 客户区中的invalid 矩形,此为应该绘制之所。

    获取DC句柄:法2

    在WM_PAINT处理之外,用GetDC得到DC,最后用ReleaseDC释放。此法返回的DC的clipping区是整个客户区,即可以随便画。而且它不会validate任何区域,若想validate整个客户区,需调用

    ValidateRect(hwnd,NULL)

    TextOut:细说

    TextOut(hdc,x,y,psTest,iLength);

    系统字体

    不同的字符宽度不一。

    字符大小

    系统字体的height和平均width。有用的函数:GetTextMetrics

    Text Metrics:细节

    LONG tmHeight ;
    LONG tmAscent ;
    LONG tmDescent ;
    LONG tmInternalLeading ;
    LONG tmExternalLeading ;
    LONG tmAveCharWidth ;
    LONG tmMaxCharWidth ;

    格式化文本

    sprintf,wsprintf,不好用printf了

    putting it all together

    例子程序:利用GetSystemMetrics获取各种属性,并打印在客户区。

    /*-----------------------------------------------
    SYSMETS.H -- System metrics display structure
    -----------------------------------------------*/
    #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
    struct  
    {
    	int iIndex;
    	TCHAR * szLabel;
    	TCHAR * szDesc;
    }
    sysmetrics[] = {
    	SM_CXSCREEN,			TEXT ("SM_CXSCREEN"),		TEXT ("Screen width in pixels"),
    	SM_CYSCREEN,			TEXT ("SM_CYSCREEN"),		TEXT ("Screen height in pixels"),
    	SM_CXVSCROLL,			TEXT ("SM_CXVSCROLL"),		TEXT ("Vertical scroll width"),
    	SM_CYHSCROLL,			TEXT ("SM_CYHSCROLL"),		TEXT ("Horizontal scroll height"),
    	SM_CYCAPTION,			TEXT ("SM_CYCAPTION"),		TEXT ("Caption bar height"),
    	SM_CXBORDER,			TEXT ("SM_CXBORDER"),		TEXT ("Window border width"),
    	SM_CYBORDER,			TEXT ("SM_CYBORDER"),		TEXT ("Window border height"),
    	SM_CXFIXEDFRAME,		TEXT ("SM_CXFIXEDFRAME"),	TEXT ("Dialog window frame width"),
    	SM_CYFIXEDFRAME,		TEXT ("SM_CYFIXEDFRAME"),	TEXT ("Dialog window frame height"),
    	SM_CYVTHUMB,			TEXT ("SM_CYVTHUMB"),		TEXT ("Vertical scroll thumb height"),
    	SM_CXHTHUMB,			TEXT ("SM_CXHTHUMB"),		TEXT ("Horizontal scroll thumb width"),
    	SM_CXICON,				TEXT ("SM_CXICON"),			TEXT ("Icon width"),
    	SM_CYICON,				TEXT ("SM_CYICON"),			TEXT ("Icon height"),
    	SM_CXCURSOR,			TEXT ("SM_CXCURSOR"),		TEXT ("Cursor width"),
    	SM_CYCURSOR,			TEXT ("SM_CYCURSOR"),		TEXT ("Cursor height"),
    	SM_CYMENU,				TEXT ("SM_CYMENU"),			TEXT ("Menu bar height"),
    	SM_CXFULLSCREEN,		TEXT ("SM_CXFULLSCREEN"),	TEXT ("Full screen client area width"),
    	SM_CYFULLSCREEN,		TEXT ("SM_CYFULLSCREEN"),	TEXT ("Full screen client area height"),
    	SM_CYKANJIWINDOW,		TEXT ("SM_CYKANJIWINDOW"),	TEXT ("Kanji window height"),
    	SM_MOUSEPRESENT,		TEXT ("SM_MOUSEPRESENT"),	TEXT ("Mouse present flag"),
    	SM_CYVSCROLL,			TEXT ("SM_CYVSCROLL"),		TEXT ("Vertical scroll arrow height"),
    	SM_CXHSCROLL,			TEXT ("SM_CXHSCROLL"),		TEXT ("Horizontal scroll arrow width"),
    	SM_DEBUG,				TEXT ("SM_DEBUG"),			TEXT ("Debug version flag"),
    	SM_SWAPBUTTON,			TEXT ("SM_SWAPBUTTON"),		TEXT ("Mouse buttons swapped flag"),
    	SM_CXMIN,				TEXT ("SM_CXMIN"),			TEXT ("Minimum window width"),
    	SM_CYMIN,				TEXT ("SM_CYMIN"),			TEXT ("Minimum window height"),
    	SM_CXSIZE,				TEXT ("SM_CXSIZE"),			TEXT ("Min/Max/Close button width"),
    	SM_CYSIZE,				TEXT ("SM_CYSIZE"),			TEXT ("Min/Max/Close button height"),
    	SM_CXSIZEFRAME,			TEXT ("SM_CXSIZEFRAME"),	TEXT ("Window sizing frame width"),
    	SM_CYSIZEFRAME,			TEXT ("SM_CYSIZEFRAME"),	TEXT ("Window sizing frame height"),
    	SM_CXMINTRACK,			TEXT ("SM_CXMINTRACK"),		TEXT ("Minimum window tracking width"),
    	SM_CYMINTRACK,			TEXT ("SM_CYMINTRACK"),		TEXT ("Minimum window tracking height"),
    	SM_CXDOUBLECLK,			TEXT ("SM_CXDOUBLECLK"),	TEXT ("Double click x tolerance"),
    	SM_CYDOUBLECLK,			TEXT ("SM_CYDOUBLECLK"),	TEXT ("Double click y tolerance"),
    	SM_CXICONSPACING,		TEXT ("SM_CXICONSPACING"),	TEXT ("Horizontal icon spacing"),
    	SM_CYICONSPACING,		TEXT ("SM_CYICONSPACING"),	TEXT ("Vertical icon spacing"),
    	SM_MENUDROPALIGNMENT,	TEXT ("SM_MENUDROPALIGNMENT"),TEXT ("Left or right menu drop"),
    	SM_PENWINDOWS,			TEXT ("SM_PENWINDOWS"),		TEXT ("Pen extensions installed"),
    	SM_DBCSENABLED,			TEXT ("SM_DBCSENABLED"),	TEXT ("Double-Byte Char Set enabled"),
    	SM_CMOUSEBUTTONS,		TEXT ("SM_CMOUSEBUTTONS"),	TEXT ("Number of mouse buttons"),
    	SM_SECURE,				TEXT ("SM_SECURE"),			TEXT ("Security present flag"),
    	SM_CXEDGE,				TEXT ("SM_CXEDGE"),			TEXT ("3-D border width"),
    	SM_CYEDGE,				TEXT ("SM_CYEDGE"),			TEXT ("3-D border height"),
    	SM_CXMINSPACING,		TEXT ("SM_CXMINSPACING"),	TEXT ("Minimized window spacing width"),
    	SM_CYMINSPACING,		TEXT ("SM_CYMINSPACING"),	TEXT ("Minimized window spacing height"),
    	SM_CXSMICON,			TEXT ("SM_CXSMICON"),		TEXT ("Small icon width"),
    	SM_CYSMICON,			TEXT ("SM_CYSMICON"),		TEXT ("Small icon height"),
    	SM_CYSMCAPTION,			TEXT ("SM_CYSMCAPTION"),	TEXT ("Small caption height"),
    	SM_CXSMSIZE,			TEXT ("SM_CXSMSIZE"),		TEXT ("Small caption button width"),
    	SM_CYSMSIZE,			TEXT ("SM_CYSMSIZE"),		TEXT ("Small caption button height"),
    	SM_CXMENUSIZE,			TEXT ("SM_CXMENUSIZE"),		TEXT ("Menu bar button width"),
    	SM_CYMENUSIZE,			TEXT ("SM_CYMENUSIZE"),		TEXT ("Menu bar button height"),
    	SM_ARRANGE,				TEXT ("SM_ARRANGE"),		TEXT ("How minimized windows arranged"),
    	SM_CXMINIMIZED,			TEXT ("SM_CXMINIMIZED"),	TEXT ("Minimized window width"),
    	SM_CYMINIMIZED,			TEXT ("SM_CYMINIMIZED"),	TEXT ("Minimized window height"),
    	SM_CXMAXTRACK,			TEXT ("SM_CXMAXTRACK"),		TEXT ("Maximum draggable width"),
    	SM_CYMAXTRACK,			TEXT ("SM_CYMAXTRACK"),		TEXT ("Maximum draggable height"),
    	SM_CXMAXIMIZED,			TEXT ("SM_CXMAXIMIZED"),	TEXT ("Width of maximized window"),
    	SM_CYMAXIMIZED,			TEXT ("SM_CYMAXIMIZED"),	TEXT ("Height of maximized window"),
    	SM_NETWORK,				TEXT ("SM_NETWORK"),		TEXT ("Network present flag"),
    	SM_CLEANBOOT,			TEXT ("SM_CLEANBOOT"),		TEXT ("How system was booted"),
    	SM_CXDRAG,				TEXT ("SM_CXDRAG"),			TEXT ("Avoid drag x tolerance"),
    	SM_CYDRAG,				TEXT ("SM_CYDRAG"),			TEXT ("Avoid drag y tolerance"),
    	SM_SHOWSOUNDS,			TEXT ("SM_SHOWSOUNDS"),		TEXT ("Present sounds visually"),
    	SM_CXMENUCHECK,			TEXT ("SM_CXMENUCHECK"),	TEXT ("Menu check-mark width"),
    	SM_CYMENUCHECK,			TEXT ("SM_CYMENUCHECK"),	TEXT ("Menu check-mark height"),
    	SM_SLOWMACHINE,			TEXT ("SM_SLOWMACHINE"),	TEXT ("Slow processor flag"),
    	SM_MIDEASTENABLED,		TEXT ("SM_MIDEASTENABLED"),	TEXT ("Hebrew and Arabic enabled flag"),
    	SM_MOUSEWHEELPRESENT,	TEXT ("SM_MOUSEWHEELPRESENT"),TEXT ("Mouse wheel present flag"),
    	SM_XVIRTUALSCREEN,		TEXT ("SM_XVIRTUALSCREEN"),	TEXT ("Virtual screen x origin"),
    	SM_YVIRTUALSCREEN,		TEXT ("SM_YVIRTUALSCREEN"),	TEXT ("Virtual screen y origin"),
    	SM_CXVIRTUALSCREEN,		TEXT ("SM_CXVIRTUALSCREEN"),TEXT ("Virtual screen width"),
    	SM_CYVIRTUALSCREEN,		TEXT ("SM_CYVIRTUALSCREEN"),TEXT ("Virtual screen height"),
    	SM_CMONITORS,			TEXT ("SM_CMONITORS"),		TEXT ("Number of monitors"),
    	SM_SAMEDISPLAYFORMAT,	TEXT ("SM_SAMEDISPLAYFORMAT"),TEXT ("Same color format flag")
    };
    //SYSMETS1.cpp
    #include <Windows.h>
    #include "SYSMETS.h"
    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
    {
    	static TCHAR szAppName[] = TEXT("SysMets1");
    	HWND hwnd;
    	MSG msg;
    	WNDCLASS wndclass;
    
    	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("fail!"),szAppName,MB_ICONERROR);
    		return 0;
    	}
    
    	hwnd = CreateWindow(szAppName,
    		TEXT("Get System Metrics No. 1"),
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		NULL,
    		NULL,
    		hInstance,
    		NULL						
    		);
    
    	ShowWindow(hwnd,iCmdShow);
    
    	UpdateWindow(hwnd);
    
    	while (GetMessage(&msg,NULL,0,0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    	//	return 0;
    }
    
    //WParam是int,LPARAM是long
    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    	static int cxChar,cxCaps,cyChar;
    	HDC hdc;
    	PAINTSTRUCT ps;
    	TCHAR szBuffer[10];
    	TEXTMETRIC tm;
    
    	switch(message)
    	{
    	case WM_CREATE:
    		hdc = GetDC(hwnd);
    		GetTextMetrics(hdc,&tm);
    		cxChar = tm.tmAveCharWidth;
    		cxCaps = (tm.tmPitchAndFamily & 1 ? 3:2) * cxChar / 2;
    		cyChar = tm.tmHeight + tm.tmExternalLeading;
    		ReleaseDC(hwnd,hdc);
    		return 0;
    	case WM_PAINT:
    		hdc = BeginPaint(hwnd,&ps);
    		for(int i =0;i < NUMLINES;i++)
    		{
    			TextOut(hdc,0,cyChar * i,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
    			TextOut(hdc,22 * cxCaps,cyChar * i,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));
    			SetTextAlign(hdc,TA_RIGHT | TA_TOP);
    
    			int len = wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].iIndex));
    			TextOut(hdc, 22 * cxCaps + 40 * cxChar, cyChar * i,szBuffer,len);
    			SetTextAlign(hdc,TA_LEFT | TA_TOP);
    		}
    		EndPaint(hwnd,&ps);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hwnd,message,wParam,lParam);
    }
    

    SYSMETS2.cpp

    #include <Windows.h>
    #include "SYSMETS.h"
    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
    {
    	static TCHAR szAppName[] = TEXT("SysMets2");
    	HWND hwnd;
    	MSG msg;
    	WNDCLASS wndclass;
    
    	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("fail!"),szAppName,MB_ICONERROR);
    		return 0;
    	}
    
    	hwnd = CreateWindow(szAppName,
    		TEXT("Get System Metrics No. 2"),
    		WS_OVERLAPPEDWINDOW | WS_VSCROLL,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		CW_USEDEFAULT,
    		NULL,
    		NULL,
    		hInstance,
    		NULL						
    		);
    
    	ShowWindow(hwnd,iCmdShow);
    
    	UpdateWindow(hwnd);
    
    	while (GetMessage(&msg,NULL,0,0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    	//	return 0;
    }
    
    //WParam是int,LPARAM是long
    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    	static int cxChar,cxCaps,cyChar,cyClient,iVscrollPos;
    	HDC hdc;
    	PAINTSTRUCT ps;
    	TCHAR szBuffer[10];
    	TEXTMETRIC tm;
    
    	switch(message)
    	{
    	case WM_CREATE:
    		hdc = GetDC(hwnd);
    		GetTextMetrics(hdc,&tm);
    		cxChar = tm.tmAveCharWidth;
    		cxCaps = (tm.tmPitchAndFamily & 1 ? 3:2) * cxChar / 2;
    		cyChar = tm.tmHeight + tm.tmExternalLeading;
    		ReleaseDC(hwnd,hdc);
    		SetScrollRange(hwnd,SB_VERT,0,NUMLINES - 1,FALSE);
    		SetScrollPos(hwnd,SB_VERT,iVscrollPos,TRUE);
    		return 0;
    	case WM_SIZE:
    		cyClient = HIWORD(lParam);
    		return 0;
    	case WM_VSCROLL:
    		switch(LOWORD(wParam))
    		{
    		case SB_LINEUP:
    			iVscrollPos --;
    			break;
    		case SB_LINEDOWN:
    			iVscrollPos ++;
    			break;
    		case SB_PAGEUP:
    			iVscrollPos -= cyClient / cyChar;
    			break;
    		case SB_PAGEDOWN:
    			iVscrollPos += cyClient / cyChar;
    			break;
    		case SB_THUMBPOSITION:
    			iVscrollPos = HIWORD(wParam);
    			break;
    		default:
    			break;
    		}
    		iVscrollPos = max(0,min(iVscrollPos,NUMLINES - 1));
    		if (iVscrollPos != GetScrollPos(hwnd,SB_VERT))
    		{
    			SetScrollPos(hwnd,SB_VERT,iVscrollPos,TRUE);
    			InvalidateRect(hwnd,NULL,TRUE);
    			UpdateWindow(hwnd);//马上绘制
    		}
    	case WM_PAINT:
    		hdc = BeginPaint(hwnd,&ps);
    		for(int i =0;i < NUMLINES;i++)
    		{
    			int y = cyChar * (i - iVscrollPos);
    			TextOut(hdc,0,y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
    			TextOut(hdc,22 * cxCaps,y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));
    			SetTextAlign(hdc,TA_RIGHT | TA_TOP);
    
    			int len = wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].iIndex));
    			TextOut(hdc, 22 * cxCaps + 40 * cxChar, y,szBuffer,len);
    			SetTextAlign(hdc,TA_LEFT | TA_TOP);
    		}
    		EndPaint(hwnd,&ps);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hwnd,message,wParam,lParam);
    }
    
  • 相关阅读:
    十五周作业
    第十四周总结
    十三周总结与感想
    排球比赛积分规则
    Centos + nginx + JBOSS AS 7 搭建Java web application
    eclipse + maven + jboss 遇到ClassNotFoundException
    “/”应用程序中的服务器错误。 纠错方法
    Sharepoint 问题集锦
    Sharepoint 问题集锦
    Sharepoint 问题集锦
  • 原文地址:https://www.cnblogs.com/speedmancs/p/1731446.html
Copyright © 2011-2022 走看看