Win32核心编程

Win32核心编程

Win32核心编程

在这里插入图片描述

Windows 编程基础

在这里插入图片描述

创建一个空白解决方案

在这里插入图片描述

创建控制台程序

在解决方案中添加一个控制台程序–》空项目
在这里插入图片描述

添加源代码
在这里插入图片描述
在这里插入图片描述

添加代码并编译执行
在这里插入图片描述

测试:成功打印
在这里插入图片描述



创建一个窗口程序

在解决方案中添加一个项目
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试:制作窗口成功
在这里插入图片描述

创建静态库程序

在解决方案中添加一个新项目 -》静态库程序
在这里插入图片描述

创建完后设置为启动项目

在这里插入图片描述
运行测试:无法运行
在这里插入图片描述

有入口 --> 可执行 --> 程序的最终文件可以进内存
没有入口 --> 无法执行

创建动态库程序

在解决方案中添加一个新项目 -》动态库程序

在这里插入图片描述

在这里插入图片描述

测试:动态库不能独立运行,需要依赖其他进程
在这里插入图片描述

三种应用程序的对比
在这里插入图片描述

windows开发环境

VC的编译工具

CL.EXE 和 LINK.EXE 可执行程序 在安装的路径下的 VC下bin
在这里插入图片描述

Windows动态库

(kernel32.dll, user32.dll, gdi32.dll 三个动态库的路径) 在 C:\Windows\System32 下
在这里插入图片描述

头文件

(几个重要的头文件所在的路径) C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include
在这里插入图片描述

一个简单的窗口程序

WinMain函数

窗口程序入口函数
句柄:
是一个用来找到内存的东西,但绝对不是指针

在这里插入图片描述

MessageBox函数

提示框

在这里插入图片描述
测试代码:hello.cpp

#include <windows.h>

int WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow)
{
   
	int ret = MessageBox(NULL, "HELLO WORLD", "INFORMATION", MB_ABORTRETRYIGNORE | MB_ICONERROR);
	if (ret == IDABORT) {
   
       	
	}
	else if (ret == IDRETRY) {
   
	
	}
	else {
   
	}
	return 0;
}

完整的编译链接的过程:

           CL.EXE
 .c/.cpp -----------> .obj|
                                      |  LINK.EXE
                                      |---------------------------> .exe
         RC.EXE                |
 .rc   -------------> .res|

在这里插入图片描述
脚本文件:hello.rc 图片名称为small.ico

100 ICON small.ico

操作步骤:
cl.exe -c hello.c -->Hello.c
rc.exe Hello.rc --> Hello.res
link.exe Hello.obj Hello.res user32.lib --> Hello.exe

在这里插入图片描述
编写窗口程序的步骤

  1. 定义WinMain函数
  2. 定义窗口处理函数(自定义,处理消息)
  3. 注册窗口类(向操作系统内核写入数据)
  4. 创建窗口(内存中创建窗口)
  5. 显示窗口(根据窗口数据在屏幕上绘制图像)
  6. 消息循环(提取消息/翻译消息/派发消息)
  7. 消息处理

参考代码:

#include <windows.h>

//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
    //回调函数
	return DefWindowProc(hWnd, msgID, wParam, lParam);  //给各种消息做默认处理
}

//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
   
	
	//注册窗口类(系统内核中写入数据)
	WNDCLASS wc = {
    0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = "Main";
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wc);  //将以上所有赋值全部写入操作系统内核
	
	//内存中创建窗口
	HWND hWnd = CreateWindowEx(0,"Main","windows",WS_OVERLAPPEDWINDOW,100,100,700,500,NULL,NULL,hIns,NULL);

	//显示窗口
	ShowWindow(hWnd, SW_SHOW);	

	//消息循环
	MSG nMsg = {
    0 };
	while (GetMessage(&nMsg, NULL, 0, 0)) {
   
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);//将消息交给窗口处理函数(自己定义的那个函数)
	}
	return 0;
}

DBCS和UNICODE编码

DBCS 与UNICODE

在这里插入图片描述

ASC - 7位代表一个字符 128个字符
ASCII - 美国国家信息标准交换码(扩展ASC码) 8位代码一个字符,256个字符
MBCS - 多字节字符编码
DBCS - 单双字节混合编码(没有统一标准) 例 A 01 我 0203 是 0405 程 0607 序 0809 源0A0B
UNICODE -万国码
utf-8 : unix 系统
utf-16: 所有字符统统按照两个字节来编码

wchar_t

在这里插入图片描述
在这里插入图片描述
参考代码:

//#define UNICODE
#include <windows.h>
#include <stdio.h>
#define WIDECHAR

void T_char() {
   
	const TCHAR* pszText = __TEXT("hello");
	//wchar_t * pszText = L"hello";
#ifdef UNICODE
	wprintf(L"%s\n",pszText);
#else
    printf("单:%s\n",pszText);
#endif
/*
#ifdef WIDECHAR
	wchar_t* pszText = L"hello";
	wprintf(L"%s\n", pszText);
#else
	const char* pszText = "hello";
	printf("单:%s\n", pszText);
#endif
*/
}


void C_char() {
   
	const char* pszText = "hello char";
	printf("%s\n", pszText);
}

void W_char() {
   
    const wchar_t* pszText = L"hello wcahr";  //宽字节字符串
	int nlen = wcslen(pszText);  
	wprintf(L"%s %d\n", pszText, nlen);
}

void PrintUnicode() {
   
	const wchar_t* pszText = L"反倒是房价快速拉升国家";
	//wprintf(L"%s\n", pszText); //对汉字打印支持不完善
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	WriteConsole(hOut, pszText, wcslen(pszText), NULL, NULL);
}

int main(void) {
   
	//T_char();
	//C_char();
	//W_char();
	PrintUnicode();
	return 0;
}

项目属性 :
Unicode字符集(IDE开发工具,增加UNICODE宏的定义)
多字节字符集(IDE开发工具,不增加UNICODE宏的定义)

<winnt.h> 中的代码

#ifdef  UNICODE                     
  typedef wchar_t TCHAR;
  #define __TEXT(quote) L##quote     
#else             
  typedef char TCHAR;
  #define __TEXT(quote) quote         
#endif   

涉及字符集的集中类型:
TCHAR char/wchar_t

LPSTR char*
LPCSTR const char*

LPWSTR wchar_t*
LPCWSTR const wchar_t*

LPTSTR TCHAR* (char*/wchar_t*)
LPCTSTR const TCHAR*

打印字符到控制台

BOOL WINAPI WriteConsole(
   HANDLE hConsoleOutput,         // 标准输出句柄
   const VOID *lpBuffer,          // 准备输出内容的buffer
   DWORD nNumberOfCharsToWrite,   // 准备输出字符串的长度
   LPDWORD lpNumberOfCharsWritten,// 返回实际输出字符串的长度
   LPVOID lpReserved              // 备用参数 NULL
);

三个标准句柄:
标准输入句柄、标准输出句柄、标准错误句柄
HANDLE WINAPI GetStdHandle(
DWORD nStdHandle
);

nStdHandle的取值
STD_INPUT_HANDLE
STD_OUTPUT_HANDLE
STD_ERROR_HANDLE

窗口的注册

在这里插入图片描述

系统窗口类的注册

在这里插入图片描述
参考代码:BUTTON

#include <windows.h>

HINSTANCE g_hIns = 0;  //接收当前程序实例句柄
void SysReg() {
   
  //不需要注册,系统已经注册
	HWND hWnd = CreateWindowEx(0, "BUTTON", "0K", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, g_hIns,NULL);
	ShowWindow(hWnd, SW_SHOW);
}


int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
   
	SysReg();
	return 0;
	
}

应用程序窗口类的注册

在这里插入图片描述

在这里插入图片描述

窗口类型风格

在这里插入图片描述

窗口的创建

CreateWindowEx (推荐使用)
在这里插入图片描述
在这里插入图片描述

参考代码:

#include <windows.h>
HINSTANCE g_hInstance = 0;
void SysReg()
{
   
	// 系统窗口类由系统注册,应用程序可以直接使用
	// 创建窗口
	HWND hWnd = CreateWindow("BUTTON","OK",WS_OVERLAPPEDWINDOW,
		100,100,700,500,NULL,NULL,g_hInstance,NULL);
	// 显示窗口
	ShowWindow(hWnd,SW_SHOW);
	// 消息循环
	MSG nMsg = {
   0};
	while(GetMessage(&nMsg,NULL,0,0))
	{
   
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);
	}
}
void AppReg()
{
   
	WNDCLASS wcs = {
   0};
	wcs.cbClsExtra = 0;
	wcs.cbWndExtra = 0;
	wcs.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcs.hCursor = NULL;
	wcs.hIcon = NULL;
	wcs.hInstance = g_hInstance; /**************/
	wcs.lpfnWndProc = DefWindowProc;
	wcs.lpszClassName = "Main";  /**************/
	wcs.lpszMenuName = NULL;
	wcs.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
	RegisterClass(&wcs);

	CreateWindow("Main","Window",WS_OVERLAPPEDWINDOW,
		100,100,700,500,NULL,NULL,g_hInstance,NULL);
}
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevIns,
	LPSTR lpCmdLine,int nCmdShow)
{
   
	g_hInstance = hInstance;
	SysReg();
	return 0;
}

子窗口的创建

在这里插入图片描述
参考代码1:主窗口关闭后进程也关闭

#include <windows.h>
#include <stdio.h>
HINSTANCE g_hIns = 0; //保存当前程序实例句柄
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
   
	switch(msgID) {
   
	case WM_DESTROY:
		PostQuitMessage(0);   //能够是GetMessage函数返回0  
		break;
	}
	return DefWindowProc(hWnd, msgID, wParam, lParam);  //给各种消息做默认处理
}

//注册窗口类
void Register(LPSTR lpClassName, WNDPROC wndproc) {
   
	WNDCLASS wc = {
    0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hInstance = g_hIns;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = lpClassName;
	wc.lpszClassName = "Main";
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wc);  //将以上所有赋值全部写入操作系统内核
}

//创建主窗口
HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName) {
   
	HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, 100, 100, 700, 500, NULL, NULL, g_hIns, NULL);
	return hWnd;
}

//显示窗口
void Display(HWND hWnd){
   
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);  //刷新窗口
}

//消息循环
void Message() {
   
	MSG nMsg = {
    0 };
	while (GetMessage(&nMsg, NULL, 0, 0)) {
   
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);  //将消息交给窗口处理函数(自定义)
	}
}

//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
   
	g_hIns = hIns;
	Register("Main", WndProc);
	HWND hWnd = CreateMain("Main", "window");
	Display(hWnd);
    Message();
	return 0;
}

参考代码2:

#include <windows.h>
#include <stdio.h>
HINSTANCE g_hIns = 0; //保存当前程序实例句柄
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
   
	switch(msgID) {
   
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msgID, wParam, lParam);  //给各种消息做默认处理
}

//注册窗口类
void Register(LPSTR lpClassName, WNDPROC wndproc) {
   
	WNDCLASS wc = {
    0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hInstance = g_hIns;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = lpClassName;
	wc.lpszClassName = "Main";
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wc);  //将以上所有赋值全部写入操作系统内核
}

//创建主窗口
HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName) {
   
	HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW, 100, 100, 700, 500, NULL, NULL, g_hIns, NULL);
	return hWnd;
}

//创建子窗口
HWND CreateChild(LPSTR lpClassName, LPSTR lpWndName, HWND hParent) {
   
	HWND hChild = CreateWindowEx(0, lpClassName, lpWndName, WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, hParent, NULL, g_hIns, NULL);
	return hChild;
}

//显示窗口
void Display(HWND hWnd){
   
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);  //刷新窗口
}

//消息循环
void Message() {
   
	MSG nMsg = {
    0 };
	while (GetMessage(&nMsg, NULL, 0, 0)) {
   
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);  //将消息交给窗口处理函数(自定义)
	}
}


//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
   
	g_hIns = hIns;
	Register("Main", WndProc);
	HWND hWnd = CreateMain("Main", "window");
	Display(hWnd);
	Register("Child",DefWindowProc);
	HWND hChild1 = CreateChild("Child", "c1", hWnd);
	HWND hChild2 = CreateChild("Child", "c2", hWnd);
	MoveWindow(hChild1, 300, 100, 200, 200, FALSE);
	MoveWindow(hChild2, 300, 100, 200, 200, FALSE);
	Message();
	return 0;
}

消息机制

在这里插入图片描述

窗口处理函数和消息

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

windows常用消息

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考代码: winMsg.cpp

// 定义自定义消息
#define WM_MYMESSAGE WM_USER + 1001
#include <windows.h>
#include <stdio.h>
HINSTANCE g_hInstance = 0;// 当前程序实例句柄
HANDLE g_hOutput = 0;  // 接收标准输出句柄
HWND g_hEdit = 0;
/*void OnCreate(HWND hWnd,LPARAM lParam)
{
	CREATESTRUCT* pcs = (CREATESTRUCT*)lParam;
	char* pszText = (char*)pcs->lpCreateParams;
	MessageBox(hWnd,pszText,"Infor",MB_OK);
}*/
void OnCreate(HWND hWnd)
{
   
	g_hEdit = CreateWindowEx(0,"EDIT","",WS_CHILD|WS_VISIBLE|WS_BORDER,
		0,0,200,200,hWnd,NULL,g_hInstance,NULL);
	// 自定义消息的发送位置任意
	// 既可以使用SendMessage,也可以使用PostMessage
//	SendMessage(hWnd,WM_MYMESSAGE,100,200);
	PostMessage(hWnd,WM_MYMESSAGE,100,200);
}
void OnMyMessage(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
   
	char szText[256] = {
   0};
	sprintf(szText,"自定义消息被处理 - wParam:%d,lParam:%d\n",
		wParam,lParam);
	MessageBox(hWnd,szText,"Infor",MB_OK);
}
void OnSize(HWND hWnd,LPARAM lParam)
{
   
	int nWidth = LOWORD(lParam);
	int nHeight = HIWORD(lParam);
	char szText[256] = {
   0};
	sprintf(szText,"WM_SIZE--宽:%d,高:%d\n",nWidth,nHeight);
	WriteConsole(g_hOutput,szText,strlen(szText),NULL,NULL);
	MoveWindow(g_hEdit,0,0,nWidth,nHeight,TRUE);
}
// 2. 窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,
	WPARAM wParam,LPARAM lParam)
{
   
	switch(msgID){
   
	case WM_MYMESSAGE:
		OnMyMessage(hWnd,wParam,lParam);
		break;
	case WM_SIZE:
		OnSize(hWnd,lParam);
		break;
	case WM_CREATE:
//		OnCreate(hWnd,lParam);
		OnCreate(hWnd);
		break;
	case WM_SYSCOMMAND:
//		return 0;
//		MessageBox(hWnd,"WM_SYSCOMMAND","Infor",MB_OK);
		if(wParam==SC_CLOSE){
   
			int nRet = MessageBox(hWnd,"是否退出?","提示",MB_YESNO);
			if(nRet==IDYES){
   
				// 什么也不写
			}else{
   
				return 0;
			}
		}
		break;
	case WM_DESTROY:
//		PostQuitMessage(0);  // GetMessage返回0?
//		SendMessage(hWnd,WM_QUIT,0,0);
		PostMessage(hWnd,WM_QUIT,0,0);
		break;
	}
	return DefWindowProc(hWnd,msgID,wParam,lParam);
}
// 3. 注册窗口类
void Register(LPCSTR lpClassName,WNDPROC wndProc)
{
   
	WNDCLASS wcs  ={
   0};
	wcs.cbClsExtra = 0;				// 窗口类附加数据缓冲区
	wcs.cbWndExtra = 0;				// 窗口附加数据缓冲区
	wcs.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);// 背景色
	wcs.hCursor = NULL;				// 光标 NULL--系统默认
	wcs.hIcon = NULL;				// 图标 NULL--系统默认
	wcs.hInstance = g_hInstance;	// 当前程序实例句柄
	wcs.lpfnWndProc = wndProc;		// 窗口处理函数
	wcs.lpszClassName = lpClassName;// 窗口类名称
	wcs.lpszMenuName = NULL;		// 菜单 NULL-没有菜单
	wcs.style = CS_HREDRAW | CS_VREDRAW;// 一般风格
	RegisterClass(&wcs);// 将以上赋值写入操作系统
}
// 4. 创建窗口
HWND CreateMain(LPCSTR lpClassName,LPCSTR lpWindowName)
{
   
	char* pszText = "Data";
	HWND hWnd = CreateWindowEx(0,lpClassName,lpWindowName,
		WS_OVERLAPPEDWINDOW,100,100,700,500,NULL,NULL,
		g_hInstance,pszText);
	return hWnd;
}
// 5. 显示窗口
void Display(HWND hWnd)
{
   
	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);
}
// 6. 消息循环
void Message()
{
   
	MSG nMsg = {
   0};
	while(GetMessage(&nMsg,NULL,0,0))
	{
   
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);
	}

/*	while(1){
		if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE))
		{
			// 有消息
			if(GetMessage(&nMsg,NULL,0,0))
			{ // 不是WM_QUIT
				TranslateMessage(&nMsg);
				DispatchMessage(&nMsg);
			}else{ // WM_QUIT
				return;
			}
		}
		else{
			// 没有消息  做空闲处理
			WriteConsole(g_hOutput,"OnIdle",6,NULL,NULL);
		}
	}*/
}
// 1. WinMain函数
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevIns,
	LPSTR lpCmdLine,int nCmdShow)
{
   
	AllocConsole();  // 增加一个DOS窗口
	g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	g_hInstance = hInstance;
	Register("Main",WndProc);
	HWND hWnd = CreateMain("Main","Window");
	Display(hWnd);
	Message();
	return 0;
}

添加DOS窗口

HANDLE g_hOutput = 0; //保存标准输出句柄

AllocConsole();
g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

消息获取

在这里插入图片描述
参考代码:

//消息循环
void Message() {
   
	MSG nMsg = {
    0 };
	/*
	while (GetMessage(&nMsg, NULL, 0, 0)) {
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);  //将消息交给窗口处理函数(自定义)
	}
	*/
	while (1) {
   
	  if(	PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE)){
   
         //有消息	
		  if (GetMessage(&nMsg, NULL, 0, 0)) {
   
			  TranslateMessage(&nMsg);
			  DispatchMessage(&nMsg);
		  }
		  else {
   
			  return;
		  }
	  }
	  else {
   
	      //空闲处理 
		  WriteConsole(g_hOutput, "OnIdld", 6, NULL, NULL);
	  }
	}
}

消息的发送

在这里插入图片描述

消息分类

在这里插入图片描述
参考代码:

void OnMyMessage(HWND hWnd, WPARAM wParam, LPARAM lParam) {
   
	char szText[256] = {
    0 };
	sprintf(szText, "自定义消息被处理:wParam=%d,1Param=%d", wParam, lParam);
	MessageBox(hWnd, szText, "Infor", MB_OK);
}

消息队列

在这里插入图片描述

在这里插入图片描述

绘图消息

在这里插入图片描述
在这里插入图片描述

参考代码:


                
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值