Windows API窗口繪圖程序設計


任務目標

設計一個簡單的Windows 窗口程序,在程序窗口內任意位置按下鼠標左鍵,可繪制范圍在10-100之間隨機大小的正方形。並且顯示的正方形用紅色填充。

效果圖

小結

程序先是觸發鼠標左鍵點擊事件,保存鼠標點擊的坐標,並生成隨機數,保存為對角的坐標,由wm_paint先畫出矩形邊框,再將矩形區域進行填充即可。這次實驗主要遇到了兩個問題,第一個是如何畫矩形。我通過百度發現可以用rectangle進行繪圖,就參考模板填寫參數即可。第二個是產生隨機數遇到問題。開始我將srand(time(null))函數放在case內,我發現每次點擊產生的矩形面積是逐漸增大,大到一定值后又從最小值開始遞增。於是我把srand(time(null))放在WndProc函數內、switch外仍然有這個問題。最后我將這個函數放在WinMain內便可以了。我思考發生這個的原因,如果在WndProc內設置種子,每當鼠標點擊一次,會運行一次WndProc,種子便設置為當前時間,因為時間差距不大,導致隨機數初始值相近並遞增。因此需要將種子設置在WinMain下,避免重復設置。

代碼

// sy1v2.cpp : Defines the entry point for the application.
//


#include<windows.h>
#include <MMSYSTEM.H>
#include <iostream>
#pragma comment(lib,"winmm.lib")
#include <time.h>
#include <stdlib.h>
using namespace std;



LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM) ;

int WINAPI WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.

	HWND hwnd;
	MSG Msg;
	WNDCLASS wndclass;
	srand(time(0));
	static TCHAR lpszClassName[]=TEXT("窗口");//窗口類名
	static TCHAR lpszTitle[]=TEXT("win窗口");//窗口標題名
	//窗口類定義
	//窗口類定義了窗口的形式與功能 窗口類定義通過給窗口類數據結構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=lpszClassName; //窗口類名為“窗口”

     if (!RegisterClass (&wndclass))
     {	
		MessageBox (NULL, TEXT ("This program requires Windows XP!"),
		lpszClassName, MB_ICONERROR) ;
		return 0 ;
     }//注冊窗口類

	hwnd = CreateWindow(
	lpszClassName,     //{窗口類的名字}
	lpszTitle,    //{窗口標題}
	WS_OVERLAPPEDWINDOW,         //{窗口樣式, 參加下表}
	CW_USEDEFAULT,CW_USEDEFAULT,          //{位置; 默認的X,Y可以指定為: Integer(CW_USEDEFAULT)}
	CW_USEDEFAULT,CW_USEDEFAULT,//{大小; 默認的寬度、高度可以指定為: Integer(CW_USEDEFAULT)}}
	NULL,       //{父窗口句柄}
	NULL,           //{主菜單句柄}
	hInstance,       //{模塊實例句柄, 也就是當前 exe 的句柄}
	NULL         //{附加參數, 創建多文檔界面時才用到, 一般設為 nil}
	);                  //{返回所創建的窗口的句柄}
	ShowWindow (hwnd, nCmdShow) ;//
	//消息循環
	while(GetMessage(&Msg,NULL,0,0)) //GetMessage()函數是從調用線程的消息隊列中取出一條消息;對於每一個應用程序窗口線程,操作系統都會為其建立一個消息隊列,當我們的窗口有消息時(即所有與這個窗口線程相關的消息),操縱系統會把這個消息放到該線程的消息隊列當中,我們的窗口程序就通過這個GetMessage()函數從自己的消息隊列中取出一條一條具體的消息並進行響應操作。
	{
		TranslateMessage(&Msg);//對"消息對"的轉化,如對鍵盤的WM_KEYDOWN和WM_KEYUP消息對轉化為WM_CHAR消息,並且將轉換后的新消息投遞到我們的消息隊列中去,這個轉化操作不會影響原來的消息,只會產生一個新的消息。
		DispatchMessage(&Msg);//DispatchMessage()函數是將我們取出的消息傳到窗口的回調函數去處理;可以理解為該函數將取出的消息路由給操作系統,然后操作系統去調用我們的窗口回調函數對這個消息進行處理。}
		//return Msg.wParam; //消息循環結束 即程序結束時 將信息返回系統
	}//
	return Msg.wParam;//
}//
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
	PAINTSTRUCT ps;//
	HDC hdc;//
	RECT rect;//
	HPEN hPen;
	LOGBRUSH logbrush;
	HBRUSH hBrush;
	int d = 0;
	static POINT pt[2];
	switch(message){//
	case WM_CREATE://
		
		return 0;//
	case WM_PAINT:///
		hdc = BeginPaint(hwnd, &ps);

        hPen = CreatePen(PS_SOLID, 4, RGB(255, 255, 0));
        SelectObject(hdc, hPen);
        //使用純畫刷
        logbrush.lbStyle = BS_SOLID;
        //使用陰影畫刷
        //logbrush.lbStyle = BS_HATCHED;
        logbrush.lbHatch = HS_CROSS;
        logbrush.lbColor = RGB(238, 0, 0);

        hBrush = CreateBrushIndirect(&logbrush);
        //畫矩形
        Rectangle(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
        //設置填充區域
        SetRect(&rect, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
        //填充顏色
        FillRect(hdc, &rect, hBrush);

        EndPaint(hwnd, &ps);
        DeleteObject(hPen);

		return 0;//
	case WM_LBUTTONDOWN:
		pt[0].x=LOWORD(lParam);
		pt[0].y=HIWORD(lParam);
		//srand(time(0));
		d = rand() % 100 + 1;
		pt[1].x=pt[0].x+d;
		pt[1].y=pt[0].y+d;
		InvalidateRect(hwnd,NULL,TRUE);
		return 0;
	case WM_DESTROY://
		PostQuitMessage (0) ;//
		return 0 ;//
	}//
	return DefWindowProc(hwnd,message,wParam,lParam);//
}//


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM