zoukankan      html  css  js  c++  java
  • 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);//
    }//
    
    
  • 相关阅读:
    C++ SDL2事件处理
    C++ SDL_Image配置
    C++ TinyXML库读写XML
    C++ libcurl库使用
    C++ 配置使用libcurl
    C++ 正则使用
    C++使用cJSON
    Vue通过状态为页面切换添加loading、为ajax加载添加loading
    移动端真机调试工具--DebugGap (VIDE)
    new Date(str)返回的时间结果在移动端比PC端快了8小时
  • 原文地址:https://www.cnblogs.com/boxker/p/10745453.html
Copyright © 2011-2022 走看看