第14次作业

15 篇文章 2 订阅 ¥79.90 ¥99.00
本次作业涉及Windows编程,实现的功能包括:左键绘制矩形,右键绘制椭圆,窗口刷新、最小化及大小调整时图形保持可见。根据指导,通过多态实现图形存盘并引入颜色变化。采用了File Editor工程来支持菜单存取操作。
摘要由CSDN通过智能技术生成

基础题目:用Windows编程,实现左键画矩形,右键画椭圆,刷新/最小化/改变窗口大小等动作,画面上的图形不会消失。

#include <windows.h>
#define MAX 10000

class Shape{
	private:
		int x1,y1;
	public:
		Shape(int x, int y): x1(x), y1(y) {}
		virtual void draw(HDC hdc,int x1,int y1,int x2,int y2)=0;
		int get_x1(){return x1;}
		int get_y1(){return y1;}
};
class MyRectangle: public Shape {
	public:
		MyRectangle(int x, int y): Shape(x,y) {}
		void draw(HDC hdc,int x1,int y1,int x2,int y2){
			Rectangle(hdc,x1,y1,x2,y2);
		}
};
class MyEllipse: public Shape {
	public:
		MyEllipse(int x, int y): Shape(x,y) {}
		void draw(HDC hdc,int x1,int y1,int x2,int y2){
			Ellipse(hdc,x1,y1,x2,y2);
		}
};

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
	static int number=0;
	static Shape* myshape[MAX];
	int xPos=LOWORD(lParam),yPos= HIWORD(lParam);
	HDC hdc;
	switch(Message) {
		case WM_LBUTTONDOWN:{
			hdc = GetDC(hwnd);
			myshape[number]= new MyRectangle(xPos,yPos);	
			//myshape[number]->draw(hdc,xPos,yPos,300,300);
			number++;
			ReleaseDC(hwnd,hdc);
			break;
		} 
		
		case WM_RBUTTONDOWN:{
			hdc = GetDC(hwnd);
			myshape[number]= new MyEllipse(xPos,yPos);	
			//myshape[number]->draw(hdc,xPos,yPos,300,300);
			number++;
			ReleaseDC(hwnd,hdc);
			break;			
		}
		case WM_PAINT:{
			hdc = GetDC(hwnd);
			for(int i=0; i<number; i++){
				myshape[i]->draw(hdc,myshape[i]->get_x1(),myshape[i]->get_y1(),300,300);
			}
			ReleaseDC(hwnd,hdc);				
			break;
		}			
		/* Upon destruction, tell the main thread to stop */
		case WM_DESTROY: {
			for(int i=0; i<number; i++)
				delete myshape[i];
			PostQuitMessage(0);
			break;
		}
		/* All other messages (a lot of them) are processed using default procedures */
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX wc; /* A properties struct of our window */
	HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
	MSG msg; /* A temporary location for all messages */

	/* zero out the struct and set the stuff we want to modify */
	memset(&wc,0,sizeof(wc));
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.lpfnWndProc	 = WndProc; /* This is where we will send messages to */
	wc.hInstance	 = hInstance;
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	
	/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszClassName = "WindowClass";
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */

	if(!RegisterClassEx(&wc)) {
		MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		640, /* width */
		480, /* height */
		NULL,NULL,hInstance,NULL);

	if(hwnd == NULL) {
		MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	/*
		This is the heart of our program where all input is processed and 
		sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
		this loop will not produce unreasonably high CPU usage
	*/
	while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
		TranslateMessage(&msg); /* Translate key codes to chars if present */
		DispatchMessage(&msg); /* Send it to WndProc */
	}
	return msg.wParam;
}

根据老师的提议,修改提升了代码,用多态进行存盘,图形会变色:
因为想使用菜单进行存储,所以使用了File Editor工程。

#include <windows.h>
#include "main.h"
#include <fstream>
#define MAX 10000
using namespace std;
/*
BOOL LoadFile(HWND hEdit, LPSTR pszFileName) {
	HANDLE hFile;
	BOOL bSuccess = FALSE;

	hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
	if(hFile != INVALID_HANDLE_VALUE) {
		DWORD dwFileSize;
		dwFileSize = GetFileSize(hFile, NULL);
		if(dwFileSize != 0xFFFFFFFF) {
			LPSTR pszFileText;
			pszFileText = (LPSTR)GlobalAlloc(GPTR, dwFileSize + 1);
			if(pszFileText != NULL) {
				DWORD dwRead;
				if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL)) {
					pszFileText[dwFileSize] = 0; // Null terminator
					if(SetWindowText(hEdit, pszFileText))
						bSuccess = TRUE; // It worked!
				}
				GlobalFree(pszFileText);
			}
		}
		CloseHandle(hFile);
	}
	return bSuccess;
}

BOOL SaveFile(HWND hEdit, LPSTR pszFileName) {
	HANDLE hFile;
	BOOL bSuccess = FALSE;

	hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
	if(hFile != INVALID_HANDLE_VALUE) {
		DWORD dwTextLength;
		dwTextLength = GetWindowTextLength(hEdit);
		if(dwTextLength > 0) {
			LPSTR pszText;
			pszText = (LPSTR)GlobalAlloc(GPTR, dwTextLength + 1);
			if(pszText != NULL) {
				if(GetWindowText(hEdit, pszText, dwTextLength + 1)) {
					DWORD dwWritten;
					if(WriteFile(hFile, pszText, dwTextLength, &dwWritten, NULL))
						bSuccess = TRUE;
				}
				GlobalFree(pszText);
			}
		}
		CloseHandle(hFile);
	}
	return bSuccess;
}

BOOL DoFileOpenSave(HWND hwnd, BOOL bSave) {
	OPENFILENAME ofn;
	char szFileName[MAX_PATH];

	ZeroMemory(&ofn, sizeof(ofn));
	szFileName[0] = 0;

	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hwnd;
	ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0";
	ofn.lpstrFile = szFileName;
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrDefExt = "txt";

	if(bSave) {
		ofn.Flags = OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
		if(GetSaveFileName(&ofn)) {
			if(!SaveFile(GetDlgItem(hwnd, IDC_MAIN_TEXT), szFileName)) {
				MessageBox(hwnd, "Save file failed.", "Error",MB_OK|MB_ICONEXCLAMATION);
				return FALSE;
			}
		}
	} else {
		ofn.Flags = OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
		if(GetOpenFileName(&ofn)) {
			if(!LoadFile(GetDlgItem(hwnd, IDC_MAIN_TEXT), szFileName)) {
				MessageBox(hwnd, "Load of file failed.", "Error",MB_OK|MB_ICONEXCLAMATION);
				return FALSE;
			}
		}
	}
	return TRUE;
}
*/


class Shape {
	private:
		int x1,y1;
	public:
		Shape(int x, int y): x1(x), y1(y) {}
		virtual void draw(HDC hdc,int x1,int y1,int x2,int y2)=0;
		virtual void save(ofstream& Outfile)=0;
		int get_x1() {return x1;}
		int get_y1() {return y1;}
};
class MyRectangle: public Shape {
	public:
		MyRectangle(int x, int y): Shape(x,y) {}
		void draw(HDC hdc,int x1,int y1,int x2,int y2) {
			Rectangle(hdc,x1,y1,x2,y2);
		}
		void save(ofstream& Outfile) {Outfile << 1 << " " << get_x1() << " " << get_y1() << endl;}
};
class MyEllipse: public Shape {
	public:
		MyEllipse(int x, int y): Shape(x,y) {}
		void draw(HDC hdc,int x1,int y1,int x2,int y2) {
			Ellipse(hdc,x1,y1,x2,y2);
		}
		void save(ofstream& Outfile) {Outfile << 2 << " " << get_x1() << " " << get_y1() << endl;}
};


static int number=0;
static Shape* myshape[MAX];
	
void Restore(HWND hwnd) {
	ifstream infile(".\\file.txt", ios::app|ios::in);
	int xPos,yPos;
	while(!infile.eof()) {
		int type;
		infile >> type;
		if(type==1) {
			infile >> xPos >> yPos;
			myshape[number]= new MyRectangle(xPos,yPos);
			number++;
		}
		else if(type==2) {
			infile >> xPos >> yPos;
			myshape[number]= new MyEllipse(xPos,yPos);
			number++;
		}
	}
	infile.close();
}

void Save(HWND hwnd) {
	ofstream outfile(".\\file.txt", ios::out);
	for(int i=0; i<number; i++){
		myshape[i]->save(outfile);
	}
	outfile.close();
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
	int xPos=LOWORD(lParam),yPos= HIWORD(lParam);
	HDC hdc = GetDC(hwnd);
	PAINTSTRUCT ps;
	HPEN hpen;
	switch(Message) {
		case WM_CREATE: {
			//CreateWindow("EDIT", "",WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_WANTRETURN,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,hwnd, (HMENU)IDC_MAIN_TEXT, GetModuleHandle(NULL), NULL);
			SendDlgItemMessage(hwnd, IDC_MAIN_TEXT, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE,0));
			SetTimer(hwnd,1,1000,NULL);
			break;
		}
		case WM_SIZE: {
			if(wParam != SIZE_MINIMIZED)
				MoveWindow(GetDlgItem(hwnd, IDC_MAIN_TEXT), 0, 0, LOWORD(lParam),HIWORD(lParam), TRUE);
			break;
		}
		case WM_SETFOCUS: {
			SetFocus(GetDlgItem(hwnd, IDC_MAIN_TEXT));
			break;
		}
		case WM_COMMAND: {
			switch(LOWORD(wParam)) {
				case CM_FILE_OPEN:
					Restore(hwnd);
					break;
				case CM_FILE_SAVEAS:
					Save(hwnd);
					break;
				case CM_FILE_EXIT:
					PostMessage(hwnd, WM_CLOSE, 0, 0);
					break;
				case CM_ABOUT:
					MessageBox (NULL, "File Editor for Windows!\nCreated using the Win32 API" , "About...", 0);
					break;
			}
			break;
		}
		case WM_TIMER: {
			switch (wParam) {
				case 1: {
					InvalidateRect(hwnd, NULL, true);
					break;
				}
				default:
					break;
			}
			break;
		}

		case WM_LBUTTONDOWN: {
			hdc = GetDC(hwnd);
			myshape[number]= new MyRectangle(xPos,yPos);
			number++;
			ReleaseDC(hwnd,hdc);
			break;
		}

		case WM_RBUTTONDOWN: {
			hdc = GetDC(hwnd);
			myshape[number]= new MyEllipse(xPos,yPos);
			number++;
			ReleaseDC(hwnd,hdc);
			break;
		}
		
		case WM_PAINT: {
			hdc = BeginPaint (hwnd, &ps);
			HPEN hpen = CreatePen(PS_SOLID, 5, RGB(rand()%256,rand()%255,rand()%254));
			SelectObject(hdc, hpen);
			
			for(int i=0; i<number; i++){
				myshape[i]->draw(hdc,myshape[i]->get_x1(),myshape[i]->get_y1(),300,300);
			}

			EndPaint (hwnd, &ps);
			DeleteObject(hpen);
			ReleaseDC(hwnd,hdc);
			break;
		}

		/* Upon destruction, tell the main thread to stop */
		case WM_DESTROY: {
			KillTimer (hwnd, 1);
			for(int i=0; i<number; i++)
				delete myshape[i]; 
			PostQuitMessage(0);
			break;
		}
		case WM_CLOSE:
			DestroyWindow(hwnd);
			break;
		/* All other messages (a lot of them) are processed using default procedures */
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	wc.cbSize        = sizeof(WNDCLASSEX);
	wc.style         = 0;
	wc.lpfnWndProc   = WndProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hInstance;
	wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName  = "MAINMENU";
	wc.lpszClassName = "WindowClass";
	wc.hIconSm       = LoadIcon(hInstance,"A"); /* A is name used by project icons */

	if(!RegisterClassEx(&wc)) {
		MessageBox(0,"Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK|MB_SYSTEMMODAL);
		return 0;
	}

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","File Editor Example Program",WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		600,480,
		NULL, NULL, hInstance, NULL);

	if(hwnd == NULL) {
		MessageBox(0, "Window Creation Failed!", "Error!",MB_ICONEXCLAMATION|MB_OK|MB_SYSTEMMODAL);
		return 0;
	}

	ShowWindow(hwnd,1);
	UpdateWindow(hwnd);

	while(GetMessage(&Msg, NULL, 0, 0) > 0) {
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值