首页 > Windows开发 > 详细

win32笔记

时间:2018-08-21 20:35:08      阅读:291      评论:0      收藏:0      [点我收藏+]

对弈的win32笔记

 

第一课:

一.Windows四大模块程序
1.1控制台程序
没有自己的窗口,dos-显示或者运行程序,入口mian()
1.2窗口程序
有自己的窗口,win32,mfc,qt,入口WinMain
1.3动态库
后缀dll,不可以单独运行,直接注入到可执行程序中
入口函数DllMain,不是必须.
1.4静态库
以lib为后缀的程序,只用来存储代码和数据.
执行程序直接赋值代码,没有入口函数
二.编译链接流程
2.1编辑器
用来写编写代码的软件,可记事本程序,或其他可编辑的软件
2.2编译器
Cl.exe把代码翻译成目标文件obj,(cl.exe 源文件名)-产生obj
2.3链接器
link.exe –把obj文件和lib或dll文件链接成exe文件
(link.exe obj的文件名 lib库名)
运行: 执行exe程序
2.4资源编辑器
rc.exe 资源文件名 (资源包括图片图标 光标 菜单)
三.第一个win32应用程序
 
四.编码方式
4.1从windowsNT开始,windows完全使用unicode来构建,所以核心函数(创建窗口,显示文本,字符串处理)都提供了unicode版本.
4.2在window中,函数通常有两个版本,一个带w(wide)结尾和带A(ASNI)结尾的;例如CreateWindowExA(….)和CreateWindowExW(…),通常情况,我们只接使用CreateWindowEx就可以,如果是unicode编码方式会有一个UNICODE的宏,会直接根据条件编译调用后缀是W版本的
4.3.windows API函数(openFile ,winExec等)只兼容于ANSI,不兼容unicode编码,所以需要转换成unicode效率低下并且转换是有可能有bug,所以用Createprocess和createfile替换,
4.4.ANSI中字符串处理 Strlen(…)
Unicode中字符串处理 Wcslen(…)
兼容版本字符串处理函数 _tcslen();
4.5unicode编码方式是两个字节代表一个字符,需要在字符串前加L,或者加_T(字符串)----兼容版本, sizeof(L“TANZHOU”) = 16,
4.6.运行安全检查:添加头文件StrSafe.h
Scanf 警告不安全,可能会操作一块布可以操作的内存.导致内存错误,所以微软重新提供_s的安全版本.
4.7.修改unicode编码方式截图如下

五.杂碎知识
5.1 messagebox详解
Int MessageBox(HWND hWnd,//窗口句柄
LPCSTR lpTt,//中间显示字符串
LPCSTR lpCap,//标题字符串
UINT uType);//显示类型


5.2 API概念
application programming interface 应用程序接口.微软为了方便windows的应用开发,提供给开发者的各种函数,这些函数就是windows操作系统提供给应用程序的接口
5.3 SDK概念
软件开发包.包含了API,说明文档,辅助开发工具.
5.4 头文件详解
windows.h---包含常用的windows的头文件,让开发者方便使用.
winbase.h---内核API接口的封装,kenel32.dll
winuser.h---用户界面相关接口的API封装,user32.lib
socket------ws2_32.lib 涉及到网络编程socket的库文件
5.5 音乐媒体处理
mmsystem.h—多媒体处理头文件,winmm.lib相关
PlaySound(
第一个: 播放音乐字符串,该参数可以是WAVE文件的名字,或是WAV资源的名字,或是内存中声音数据的指针,或是在系统注册表WIN.INI中定义的系统事件声音。如果该参数为NULL则停止正在播放的声音

第二个:参数hmod是应用程序的实例句柄,除非pszSound的指向一个资源标识符(即fdwSound被定义为SND_RESOURCE),否则必须设置为NULL。

第三个:参数fdwSound是标志的组合

SND_SYNC ---同步播放声音,在播放完后PlaySound函数才返回。
SND_ASYNC---用异步方式播放声音,PlaySound函数在开始播放后立即返回。

SND_FILENAME---pszSound参数指定了WAVE文件名。
SND_RESOURCE --pszSound参数是WAVE资源的标识符,这时要用到hmod参数。

SND_PURGE---停止声音。若参数pszSound为NULL,就停止所有的声音,否则,停止pszSound指定的声音。
SND_NOSTOP ----PlaySound不打断原来的声音播出并立即返回FALSE。
SND_LOOP---重复播放声音,必须与SND_ASYNC标志一块使用。


利用MCI 接口实现播放任意格式声音
1.#include <mmsystem.h> //导入声音头文件库   
2.#pragma comment(lib,"winmm.lib")//导入声音的链接库  
然后直接用mciSendString函数即可
1.mciSendString("open C:/123.mp3" , NULL, 0, 0);  
2.mciSendString("play C:/123.mp3 ", NULL, 0, 0); 
3.mciSendString("close movie",buf,sizeof(buf),NULL);
4.  
5.LPCTSTR lpszCommand, // 指向以null结尾的命令字符串:”命令 设备[ 参数]”
6.LPTSTR lpszReturnString,// 指向接收返回信息的缓冲区,为NULL时不返回信息
7.UINT cchReturn, // 上述缓冲区的大小
8.HANDLE hwndCallback // 在命令串中含notify时,它指定一个回调窗口的句柄
9.// 一般为NULL
10.);
11.如:mciSendString(L"open sample.wav type waveaudio alias wave", NULL, 0, NULL);
 
6.作业
创建一个windows应用程序,循环异步播放音乐(wav格式)用messagebox弹出一段”脏”话,如果点击’是’则结束程序,如果点击’否’则继续弹出一个框,直到点击10次否后,提示关机倒计时10秒,然后关机
 
 

第二课:

一.窗口创建步骤
1.1 定义程序入口winmain函数
1.2 注册窗口
1.2.1 窗口类
typedef struct { UINT style; // 窗口类风格
    WNDPROC lpfnWndProc; // 窗口过程函数指针
int cbClsExtra; // 窗口类附加数据缓冲区字节数
    int cbWndExtra; // 窗口附加数据缓冲区字节数
    HINSTANCE hInstance; // 当前应用程序实例句柄
    HICON hIcon; // 图标句柄
    HCURSOR hCursor; // 光标句柄
    HBRUSH hbrBackground; // 刷子句柄
    LPCTSTR lpszMenuName; // 菜单资源名
    LPCTSTR lpszClassName; // 窗口类名 } WNDCLASS, *PWNDCLASS;
注意: WNDCLASSE中多了一个 UINT cbSize; // 结构体字节数*
1.2.2 窗口类风格
CS_GLOBALCLASS - 应用程序全局窗口类
CS_BYTEALIGNCLIENT - 窗口客户区水平位置按8像素对齐
CS_BYTEALIGNWINDOW - 窗口水平位置按8像素对齐
CS_HREDRAW - 窗口水平变化时重绘
CS_VREDRAW - 窗口垂直变化时重绘
CS_DBLCLKS - 允许窗口接收鼠标双击消息
CS_NOCLOSE - 没有关闭按钮
1.2.3注册窗口函数
ATOM RegisterClass (CONST WNDCLASS* lpWndClass);
ATOM即unsigned short,成功返回所注册窗口类的唯一标识码(非0), 失败返回0。
1.3 消息处理
LRESULT CALLBACK WindowProc (
HWND hWnd, // 窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 消息参数
LPARAM lParam // 消息参数 )
LRESULT CALLBACK DefWindowProc (
HWND hWnd, // 窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 消息参数
LPARAM lParam // 消息参数 );
案例:DefWindowProc函数对WM_DESTROY消息的处理不会投递WM_QUIT消息,
导致消息循环不会结束,窗口虽然关闭,但进程仍然存在。
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, uMsg, wParam, lParam); }
1.4 创建窗口:
1.4.1创建窗口函数:在内存中创建窗口对象,并不可见
HWND CreateWindow (
LPCTSTR lpClassName, // 窗口类名
LPCTSTR lpWindowName, // 窗口标题栏信息
DWORD dwStyle, // 窗口风格
int x, // 窗口左上角水平坐标
int y, // 窗口左上角垂直坐标
int nWidth, // 窗口宽度
int nHeight, // 窗口高度
HWND hWndParent, // 父窗口句柄
HMENU hMenu, // 菜单句柄
HINSTANCE hInstance, // 当前应用程序实例句柄
LPVOID lpParam // 附加数据 )
1.4.2 窗口风格
WS_OVERLAPPED:用于产生一个叠层窗口,都有标题栏和边框
WS_CAPTION:有标题栏的窗口
WS_SYSMENU:创建一个标题栏上具有系统菜单的窗口,需要ws_caption一起使用
WS_MINIMAZEBOX:创建具有最小化按钮窗口,必须有ws_system类型
WS_MAXIMIZBOX:创建具有最大化按钮的窗口,必须有ws_system类型。
WS_OVERLAPPEDWINDOW:创建有标题栏,系统菜单最大化最小化窗口
WS_POPUP - 弹出式
WS_POPUPWINDOW - 边框、弹出式、系统菜单
WS_SIZEBOX - 带尺寸框的粗边框
WS_SYSMENU - 系统菜单
1.5 窗口显示
BOOL ShowWindow ( //成功返回TRUE,失败返回FALSE。
HWND hWnd, // 窗口句柄
int nCmdShow // 显示方式 );
BOOL UpdateWindow( HWND hWnd // 窗口句柄 );//刷新
成功返回TRUE,失败返回FALSE。
1.6 消息循环
重复执行提取消息、翻译消息、派发消息三步
BOOL GetMessage ( //收到WM_QUIT返回FALSE,收到其它消息返回TRUE
LPMSG lpMsg, // 消息结构
HWND hWnd, // 窗口句柄
UINT wMsgFilterMin, // 起始消息
UINT wMsgFilterMax // 终止消息 );
BOOL TranslateMessage ( //将虚键消息翻译为字符消息。
const MSG* lpMsg // 消息结构 );
若消息被翻译则返回TRUE,否则返回FALSE。
LRESULT DispatchMessage ( //将消息派发到窗口过程函数。
const MSG* lpmsg // 消息结构 );
返回窗口过程函数的返回值
1.7 注销窗口
UnregisterClass。进程结束时,其所注册的全部窗口类都会被自动注销
1.8 完整代码展示
 
 
二.基本概念汇总
2.1句柄概念
在windows应用程序中,窗口都是通过句柄进行标识的,
当系统创建这些资源的时候会分配内存,并返回资源标志号—句柄
2.2加载图标
LoadImage(实例句柄,文件名,图片类型,指定图标或光标的宽度,高度,加载方式);
IMAGE_BITMAP:装载位图;
IMAGE_CURSOR:装载光标;
IMAGE_ICON:装载图标。
LR_DEFAULTSIZE ---默认大小
LR_DEFAULTCOLOR:缺省标志;它不作任何事情
LR_LOADFROMFILE---从文件中加载
2.3移动窗口
BOOL MoveWindow(
HWND hWnd, // 窗口句柄
int X, // 水平坐标
int Y, // 垂直坐标
int nWidth, // 窗口的宽
int nHeight, // 窗口的高
BOOL bRepaint // 是否擦除原来的);
 
 

第三课

一.消息基本概念
1.1 消息队列:
当windows应用程序开始执行时,系统会为该程序建立一个消息
队列用于存放消息,然后用getmessage等进行消息获取处理。
程序从队列中获取消息后处理.分为系统消息队列(有系统维护,
存放系统产生的消息如键盘鼠标消息)程序消息队列(存放应用
程序消息应用程序自行处理)
过程:事件- 封装消息-投递消息队列-消息相应
1.2 消息分类:
系统消息:系统已经定义好的消息WM_DESTRY等(0~0x03FF)
自定义消息:用户自行定义 WM_USER+10等;(0x400~0x7fff)
队列消息:消息发送和获取都是在消息队列
(WM_PAINT,鼠标键盘定时器消息)
GetMessage--从消息队列获取消息
PostMessage-将消息投放到消息队列
非队列消息:不进队列直接消息处理函数完成
(WM_CREATE,WM_SIZE)
1.3 MSG结构体信息
typedef struct tagMSG {
HWND hwnd; //指定消息所处的窗口
UINT message; //指定消息的标识符 (宏定义处理方便)
WPARAM wParam;//MSG的附加消息
LPARAM lParam;//附加消息
DWORD time;//投递到消息队列的事件
POINT pt;//投递时鼠标当前位置
} MSG
二.消息获取/发送函数
GetMessage-从消息队列中获取一个消息后移除(堵塞),当队列中
无消息获取则等候下一个消息
PeekMessage---查看消息队列中消息,非堵塞,无消息是返回false
 
 
SendMessage--把消息发送到指定窗口,直接消息处理函数处理,获取到返回结果后结束(堵塞)
PostMessage--将消息放入指定窗口消息队列,不等待结果直接返回(非堵塞)
三.消息处理过程(getMessage)
从当前程序的消息队列中进行查找,如果有消息则判断是否满足窗口句柄,id范围等条件.满足的话取出消息发送给消息处理函数后返回,如果不满足则向系统消息队列获取属于本进程的消息,如果找到满足条件的则把系统中消息队列中的存入本程序消息队列中.如果系统消息队列也没有则检查窗口是否重绘,是则产生WM_PAIT消息,然后返回处理,如果没有重绘,查看定时器有没有需要处理,有则产生WM_TIMER消息.如果没定时器则优化资源,处理内存.然后等候下一个消息(PEEKmessage不会等待,会直接返回false后交出程序的控制权)
处理过程:查找本程序消息---> 如果消息队列有则判断是否满足条件(ID)—>满足取出消息(不满足不取)--查窗口相关系统消息(如无程序消息)--转去程序消息(如有)-检查重绘(如无系统消息)---->发送wm_paint消息-----检查定时器(如无重画)-整理程序资源内存-等待
四.控制台显示(穿插)
1.AllocConsole() 为调用进程分配一个新的控制台
2.获取标准输出HANDLE g_h = GetStdHandle(STD_OUTPUT_HANDLE)
3.char szText[256] = { 0 }; sprintf(szText, “%s\n”, “wm_size” );
BOOL WriteConsole(
HANDLE hConsoleOutput,//操作的句柄
CONST VOID * lpBuffer,//需要写入的内容
DWORD nNumber, //写入的字节数
LPDWORD lpNu,//指向接收实际写入字节数的变量指针可为NULL
LPVOID lpReserved//必须为NULL );
五.重要消息(1)
5.1 窗口创建消息:WM_CREATE
5.2 重绘消息 WM_PAINT
5.3 定时器消息: WM_TIMER(暂时讲)
SetTimer( hWnd, 2, 2000, TimerProc );
 
 

第四课

一.鼠标消息
1.1.鼠标左键消息
WM_LBUTTONDOWN 鼠标左键单击按下
WM_LBUTTONUP 鼠标左键单击弹起
WM_LBUTTONDBLCLK 鼠标左键双击
1.2.鼠标右键消息
WM_RBUTTONDOWN 鼠标右键按下
WM_RBUTTONUP 鼠标右键弹起
WM_RBUTTONDBLCLK 鼠标右键双击
1.3左键右键消息参数
(双击消息必须注册时加上CS_DBLCLKS)
WPARAM ---其他按键状态,例如CTRL/shift等
LPARAM-----鼠标的坐标系(客户区而言)
LOWORD----X坐标 HIWORD-------y坐标
1.4鼠标移动(滚轮)
WM_MOUSEMOVE 鼠标移动消息
WM_MOUSEWHEEL 鼠标滚轮消息
1.5滚轮消息参数
WPARAM:
LOWORD-----其他按键状态 HIWORD-----滚轮偏移(120倍数,向前为正)
LPARAM:
LOWORD ------x坐标 HIWORD----y坐标

二.键盘消息
2.1虚拟键码
在windows中,所有键盘的按键都被定义为一组通用的虚拟键码,所有键都视为虚拟键,每个键都对应的虚拟键码。(WINUSER.H定义)
VK_LEFT, VK_RIGHT,VK_ESC等(查看虚键码值表)
2.2普通键盘消息
Wm_KEYDOWN 键盘按下消息
WM_KEYUP 键盘弹起消息
附加参数作用:
WPARAM 按键的虚拟键码值
LPARAM 按键的参数(按下的次数等)
2.3系统按键消息
WM_SYSKEYDOWN 系统按键 F10 alt等
WM_SYSKEYUP 系统键放下时消息
附加参数作用:
WPARAM 按键的虚拟键码值
LPARAM 按键的参数(按下的次数等
2.4字符消息
WM_CHAR 字符消息(当键盘按下可见字符时,先产生WM_KEYDOWN消息,TranslateMessage转换成WM_CHAR消息,)
附加参数作用
WPARAM 输入的字符
LPARAM 按键的相关信
三.定时器消息:
每过多少毫秒就相应一次,相当于时间上的循环处理
WM_TIMER消息(处理时间是毫秒,不准确)
WPARAM----定时器ID
LPARAM----定时器处理函数指针
定时器使用:
UINT_PTR SetTimer(HWND h,UINT nID,UINT time,TIMERPROC lp)
关闭定时器:
BOOL killTimer(HWND hWND,UNIT_PTR uIDEvent0);
四.重绘消息:
当窗口需要绘制的时候,会发送WM_PAIT消息给处理函数
Bool InvalidateRect(HWND hWnd,
const RECT* LpRect ,BOOL erase//重绘前是否删除)
WM_PAINT WPARAM---LPARAM参数无用
SendMessage(hWnd, WM_MYMESSAGE, 0, 0);
 

第五课

1.菜单分类
顶层菜单--在我们窗口上面的菜单
右键菜单--鼠标右键出现的菜单
系统菜单--点击非客户区右键弹出的菜单
2.系统菜单
2.1.获取系统菜单
返回菜单句柄GetSystemMenu(窗口句柄, 标志);
标志:true--- 删除旧菜单,回复到默认菜单
False—返回当前系统菜单
2.2删除系统菜单
DeleteMenu(菜单句柄, 标记, 删除方式);
删除方式:MF_BYCOMMAND:为默认值。说明参数nIDCheckItem表示菜单项的ID
MF_BYPOSITION:说明参数Item表示菜单项的位置,第一个菜单项的位置是0
2.3 添加系统菜单
AppendMenu(菜单句柄, 模式,菜单ID,显示字符);
MF_STRING:添加的是字符串
MF_BITMAP:将位图用作菜单项。lpNewltem里含有该位图的句柄。
MF_DISABLED:菜单项无效,该项不能被选择,菜单项不变灰。
MF_ENABLED:菜单项有效,使该项能被选择,从变灰的状态恢复。
MF_GRAYED:使菜单项无效并变灰,使其不能被选择。
MF_OWNERDRAW:指定该菜单项为自绘制菜单项。(菜单第一次显示前,拥有菜
单的窗口接收一个WM_MEASUREITEM消息来得到菜单项的宽和高。
只要菜单项被修改,都将发送WM_DRAWITEM消息给菜单拥有者的窗口程序)
MF_POPUP:指定菜单打开一个下拉式菜单或子菜单。
MF_SEPARATOR:画一条水平区分线,下拉式菜单使用。参数IpNew和uID无用。
2.4系统菜单相应
WM_SYSCOMMEND消息.wparam的低字节是菜单ID.
3右键菜单
3.1创建菜单
CreatePopupMenu()创建右键菜单,是弹出式菜单,创建后返回句柄
3.2添加显示
添加菜单项:AppendMenu()参数如上
显示菜单:
TrackPopupMenu( 菜单句柄 显示方式 屏幕x坐标,屏幕Y坐标,0,窗口句柄,NULL )
注意:右键消息得到的x和y是客户端坐标,需要转换成屏幕坐标
POINT p; p.x = LOWORD(WPARAM) p.y = HIWORD(WPARAM);
客户端转换成屏幕坐标:ClienttoScreen(窗口句柄,point指针)
3.3消息响应:
点击菜单发送: WM_COMMAND消息 wparam的低字节是菜单ID.
4.顶层菜单
4.1顶层菜单
顶层菜单 = 多个弹出式菜单项+弹出式菜单每一项
创建顶层菜单: HMENU hMenu = CreateMenu(void)
创建弹出式菜单: HMEUE createPopupMenu(void);
把弹出式菜单插入顶层菜单:
AppendMenu(顶层菜单句柄, MF_POPUP,弹出式菜单句柄,菜单名称);
AppendMenu(弹出式菜单句柄,菜单风格,菜单ID,菜单名称 )
4.2.菜单消息响应
WM_COMMEND ----- WPARA 低字节保存的是菜单的ID
根据菜单的id处理不同的菜单项
 
 

第六&七课

一.GDI概念
概念: 图形设备接口(API),Graphics Device Interface。他是微软设计的一套API,GDI是windows图形显示程序与实际物理设备之间的一个桥梁。使用者不需要关心硬件设备,只管调用API就好
GDI的特点:不直接访问物理显示硬件,通过”设备环境”的抽象接口访问
程序与硬件(显示器等)交互时,必须获得与相对应设备环境。
使用者不用关心物理设备类型
设备环境(Device Context):简称DC,也叫做设备上下文,设备描叙表。DC就是程序可以进行绘图的地方:例如我们要在平屏幕绘图,设备就屏幕吧,而dc就是屏幕上的绘图层
设备句柄:设备上下文句柄,设备环境句柄,简称HDC.如果需要绘图,首先得得到句柄,绘图完成之后必须释放句柄
基本概念:
位图:位的矩形数据,这些位对应显示设备上的像素,简称BMP(bitmap),可以分为设备相关位图(DIB)和设备无关位图(DIB) ,我们一般使用的是DIB.
文字:GDI支持TrueType字体,这种字体是在填充轮廓线基础上建立的。实际上就是TTF后缀的字体
颜色: RGB R=0~255,G = 0~255, R = 0~255;红绿蓝,例如RGB(123,234,123)
二. 取得获取上下文句柄API
第一对好基友:
BeginPaint(窗口句柄, PAINTSTRUCT结构体指针;); 返回设备句柄
EndPaint(窗口句柄, 结构体指针);
第二对好基友:
GetDC(窗口句柄);//返回上下文句柄
ReleaseDC(窗口句柄,设备句柄);
三.图形绘制
3.1画笔
HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor);
参数1:样式 PS_SOLID实现实线PS_DASH短线
PS_DOT点 PS_DASHDOT 短线点
第二个参数: 画笔的宽度
第三个参数: 颜色RGB,直接构建 COLORREF color = RGB(255,255,255)
3.2画刷
实心画刷:HBRUSH CreateSolidBrush(颜色)
阴影画刷: HBRUSH CreateHatchBrush(样式,颜色)
HS_BDIAGONAL---正斜线, HS_FDIAGONAL----反斜线
HS_DIAGCROSS---正反交叉 HS_CROSS---井字格
位图画刷: CreatePatternBrush(位图句柄)
HBITMAP hBmp = LoadBitmap( g_hInstance,MAKEINTRESOURCE(IDB_BITMAP1) );
     HBRUSH hBrush = CreatePatternBrush( hBmp );
3.3设定设备上下文参数
直白点就是把画笔等应用到DC中
Selectobject(设备上下文句柄,需要选择的句柄);//画刷句柄,文字等
deleteSObject(需要删除的其他句柄); //删除句柄,释放内存
3.4画点
COLORREF SetPixel(设备句柄,x,y,RGB);//返回原来点颜色
GetPixel()获取某个点的颜色
3.5 画线
LineTo(设备环境句柄,终点x,终点y) true划线成功 否则失败
MoveToEx(设备环境句柄,起点x,起点Y,NULL);
3.6画圆
BOOL Ellipse(HDC hdc, int nLeftRect, int nTopRect,
nRightRect, int nBottomRect);//参数左顶右底
3.7画矩形
Rectangle(上下文句柄,左角x,左角y,右下x,右下y);
成功返回非0,读法:
RoundRect(  DC: HDC;   X1, Y1, X2, Y2, X3, Y3)’//圆角矩形
点1、点2是构成矩形的坐标; X3是圆角宽度、Y3是圆角高度
3.8画图
1 得到dc
2 创建兼容dc
3 加载位图
LoadImage(实例句柄,位图名,图片类型,宽,高,加载方式);
4.选用位图对象 selectobject()
5.进行贴图 bitblt()
刷新区域
ValidateRect(窗口句柄,const RECT * L);//更新窗口,第二个参数NULL
3.9文字
文字输出函数:
TextOut(文字输出DC句柄,x坐标,y坐标,字符串指针,字符串个数)
DrawText(设备句柄,字符串,字符串长度,LPRECT绘制区域,绘制模式)
绘制模式如下:
DT_BOTTOM--底部对齐,和DT_SINGLELINE一起使用
DT_LETF DT_RIGHT DT_TOP DT_SINGLELINE 单行显示
设置文字颜色:COLORREF SetTextColor(设备句柄,颜色)
设置文字背景透明:SetBKMode(设备句柄,模式)
模式:QPAQUE 不透明 TRANSPARENT----透明
创建字体:
BOOL CreateFont( int nHeight逻辑高度, 
int nWidth逻辑宽度, 
int nEscapement显示角度, //显示的坡度
int nOrientation字体角度, //水平上字体的斜角度
int nWeight字体磅数,
BYTE bItalic是否斜体, 
BYTE bUnderline是否下划线,
                    BYTE cStrikeOut是否删除线, 
BYTE nCharSet所需字符集,
                    BYTE nOutPrecision输出精度,
BYTEnClipPrecision裁剪精度, 
BYTE nQuality输出质量,
                    BYTE nPitchAndFamily字符间距的字符集, 
LPCTSTR lpszFacename字体名称 );
BOOL PolyTextOut(HDC hdc, CONST POLYTEXT *pptxt, int cStrings);
功能:在指定设备环境下以当前所选的字体和正文颜色绘制多个字符串。
CreateFontIndirect 可以用来设置字体属性等
 
 

第八课

一.对话框
1.1对话框基本概念
1) 是一种特殊的窗口,主要用于响应用户的输入,布局控件
    2) 对话框的创建可以直接在资源脚本.rc文件中通过脚本定义
3)对话框分类:
模式对话框 -(堵塞)即模态对话框,对对话框以外的应用程序窗口操作时,须先对该对话框进行响应。
     非模式对话框 -(非堵塞) 在对话框显示后,其他窗口同样可以接收输入等用户交互操作。
1.2对话框基本使用步骤
1.添加对话框资源
2 添加对话框处理函数
3 注册对话框窗口类
4 创建对话框
5 关闭
二.模式对话框
2.1处理函数
INT DialogProc(HWND hDlg, UINT uMsg, WPARAM w,    LPARAM lParam);
返回TRUE - DialogProc函数中处理了这个消息,缺省处理函数不需要处理。
返回FALSE- DialogProc函数未处理这个消息,交给缺省处理函数处理。
不需要调用缺省对话框窗口处理函数。
2.2 创建对话框
    INT_PTR DialogBox( HINSTANCE h,
     LPCTSTR ID, //对话框模板资源ID
     HWND hParentWnd, //对话框父窗口
     DLGPROC lpDialogFunc //对话框窗口处理函数
    );      
    DialogBox是一个阻塞函数,只有当对话框关闭后才会返回,继续执行后续代码。    返回值是通过EndDialog设置。
2.3 关闭对话框
    BOOL EndDialog(
         HWND hDlg,//关闭的对话框窗口句柄
         INT_PTR nResult //关闭的返回值
    );
    关闭模式对话框,只能使用EndDialog,不能使用DestroyWindow等函数。
    nResult是DialogBox函数退出时的返回值。
2.4 对话框的消息
    WM_INITDIALOG - 对话框创建之后显示之前,通知对话框窗口处理函数,可以完成自己的初始化相关的操作。
2.5.底层实现
1. 让父窗口失效 EnableWindow(parentWindow, FALSE)
2. 建立模态对话框自己的消息循环(RunModalLoop)
3. 直至接收关闭消息,消息循环终止,并销毁窗口。
三.非模式对话框
3.1 创建对话框
    HWND CreateDialog(
        HINSTANCE hInstance, //应用程序实例句柄
         LPCTSTR lpTemplate, //模板资源ID
         HWND hWndParent, //父窗口
         DLGPROC lpDialogFunc //窗口处理函数
    );
    非阻塞函数,创建成功返回窗口句柄,需要使用ShowWindow函数显示对话框。
3.2 处理函数
INT DialogProc(HWND hDlg, UINT uMsg, WPARAM w,  LPARAM lParam);
3.3 关闭对话框
    关闭时使用DestroyWindow销毁窗口,不能使用EndDialog关闭对话框。
四. 总结
4.1创建关闭的区别
    模式对话框 - 创建: DialogBox,阻塞函数
- 关闭:EndDialog
    非模式 - 创建: CreateDialog
- 关闭:DestroyWindow
    普通窗口 - CreateWindow/Ex
DestroyWindow
4.2 窗口消息区别
    普通窗口 - WM_CREATE
    对话框 - WM_INITDIALOG
 
 

第九课

一.控件概念
·控件:特殊的一类”子”窗口,系统已经定义好了窗口类型.
创建方式和创建窗口类似,调用createWindows,每个控件都由ID
·父窗口直接通过sendmessage向控件发送消息.
控件事件发生后,会向所在的父窗口发送通知消息
·注意:创建窗口时必须添加两个属性
WS_CHILD:控件是放在我们的窗口上的,自然要作为窗口的子窗口
WS_CHILDWINDOW也一样,为了节约几个字母,用WS_CHILD吧。
WS_VISIBLE:设置可见,要想别人称赞你老婆漂亮,先让别人见你老婆
·创建窗口函数讲解
HWND WINAPI CreateWindow( 类名, 显示内容,  风格,  nt x,   int y,   
int nWidth,  int nHeight,  父窗口,  控件ID,  
HINSTANCE hInstance,  LPVOID lpParam  );
·主要控件:按钮,编辑框,静态框,列表框,组合框,树控件,分组框,等
二.按钮
2.1基本概念
窗口类名 BUTTON
按钮分类:
下压式按钮 BS_PUSHIBUTTON/BS_DEFPUSHIBUTTON
复选框 BS_CHECKBOX/BS_AUTOCHECKBOX /BS_3STATE/ BS_AUTO3STATE
单选框BS_RADIOBUTTON/BS_AUTORADIOBUTTON
分组框BS_GROUPBOX
2.2下压式按钮
创建按钮:
CreateWindow(L"Button", L"按钮一", WS_VISIBLE | WS_CHILD |
  BS_PUSHBUTTON,     .... hwnd, (HMENU)IDB_ONE, hg_app, NULL); 
按钮消息:WM_COMMAND
LOWORD(wParam) --- 保存的是按钮ID
HIWORD(wparam)---通知码BN_CLICKED
lParam 子窗口句柄
 
改变按钮文本信息: 向控件发送 WM_SETTEXT
    
2.3 分组框
窗口名称BUTTON
窗口风格 BS_GROUPBOX
2.4单选框
窗口名称BUTTON
窗口风格BS_RADIOBUTTON / BS_AUTORADIOBUTTON/WS_GROUP
WS_GROUP的单选框,到下一个WS_GROUP单选框之前,为1组
     获取和设置选择状态(通知消息是BN_CLICKED)
     BM_SETCHECK
     BM_GETCHECK  
案例:if( HIWORD(wParam)==BN_CLICKED )         {
                HWND h3State = GetDlgItem( hWnd, 1005 );
                LRESULT nRet = SendMessage( h3State, BM_GETCHECK, 0, 0 );
                if( nRet == BST_CHECKED )}
2.5复选框
窗口类名:BUTTON
窗口风格:
BS_CHECKBOX - 点击选择时,需要自己维护选择状态
BS_AUTOCHECKBOX - 点击选择时,系统自动维护选择状态
BS_3STATE --变灰的三种状态
BS_AUTO3STATE-自动处理的三种状态
获取和设置选择状态(通知消息是BN_CLICKED)
BST_INDETERMINATE-设置灰色
BST_CHECKED ---设置选择
BST_UNCHECKED --设置不选择
设置状态SendMessage(... BM_SETCHECK,具体状态,必须为0);
获取状态SendMessage(... BM_GETCHECK,0,0);
案例SendMessage( 句柄, BM_SETCHECK,BST_INDETERMINATE, 0 );
三. 编辑框
3.1基本概念
窗口类名 EDIT
分类:
文字编辑框:显示单行文字/显示多行文字
密码编辑框:ES_PASSWORD,显示密码
窗口风格
 
3.2通知消息
在WM_COMMAND case下 处理这个参数
if (HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) == nEditID)
3.2.1 WM_GETTEXT ---获取编辑框文本
wPararm - buffer 的大小 lPararm – buffer的首地址
SendMessage( (WPARAM) wParam, // number of characters to copy
(LPARAM) lParam // text buffer);
3.2.2 WM_GETTEXTLENGTH-获取文本长度
SendMessage( (WPARAM) 0, (LPARAM) 0)
3.2.3 WM_SETTEXT设置内容
wParam – 没用,lParam – 准备设置内容的buffer的首地址
补充:
· SendMessage( hWndEdit, WM_CUT, 0, 0 );  
· SendMessage( hWndEdit, WM_COPY, 0, 0 );  
· SendMessage( hWndEdit, WM_CLEAR, 0, 0 )

 
四. 静态框:
窗口名称 “STATIC” 用来用来显示文字,加载图片(设置属性 SS_ICON/SS_BITMAP)
窗口消息: sendMessage 发送到控件即可 例如 STM_SETICON
通知消息: 需要创建时增加SS_NOTIFY风格
通知消息通过WM_COMMAND 消息传递
LOWORD(wparam)---控件ID
HIWORD(wparam)---notify-code(STN_CLICKED)
Lparam---控件窗口句柄

 CreateWindowEx的拓展风格
WS_EX_NODRAG:防止窗口被移动
WS_EX_ACCEPTFILES: 接受一个拖拽文件。
WS_EX_APPWINDOW:当窗口可见时,将一个顶层窗口放置到任务条上。
WS_EX_CLIENTEDGE:指定窗口有一个带阴影的边界。
WS_EX_CONTEXTHELP:在窗口的标题条包含一个问号标志。当用户点击了问号时,鼠标光标变为一个问号的指针、如果点击了一个子窗口,则子窗口接收到、
WS_EX_DLGMODALFRAME:创建一个带双边的窗口;
 
五.组合框
5.1组合框分类
简单组合框 CBS_SIMPLE (可以输入可以选择)
下拉式组合框 CBS_DROPDOWN (可以输入,可以选择)
下拉式列表组合框 CBS_DROPDOWNLIST (只可以选择不可以输入)

5.2组合框发送消息
CB_ADDSTRING ----添加项(WPARAM---没用 LPARAM----字符串指针)
CB_INSERTSTRING 添加项
CB_DELETESTRING 删除制定项
CB_RESETCONTENT 清除所有项
CB_SETCURSEL 设置当前项
CB_GETCURSLE 获取当前项
CB_FINDSTRING 查找某项字符串
CB_GETLBTEXTLEN 获取选择的字符长度
CB_GETLBTEXT 获取选项的一个字符内容
CB_DIR 在组合框中显示制定路径下的文件和目录名字
CB_SETITENDATA 将数据保存到指定选项中
CB_GETITEMDATA 从指定选项中获取数据

5.3向父窗口消息
当选择项发送改变时 会给父窗口发送 CBN_SELCHANGE消息
当输入内容发送改 变时 会给父窗口发送 CBN_EDITCHANGE
六.杂烩知识点
UNREFERENCED_PARAMETER
最高级别的警告 Level 4(/W4)进行编译时。例如在程序中定义一个变量未使用就会提出警告.你可以加上UNREFERENCED_PARAMETER为了骗过编译器。对某个变量不需要提供警告信息
LoadString把String Table里面的字符串读出来到CString对象里
LoadAccelerators加载快捷键,返回快捷键句柄
TranslateAccelerator把消息跟快捷键表里定义的按键进行比较,如果发现有快捷键,就会把这个按键消息转换为WM_COMMAND或者WM_SYSCOMMAND消息给窗口的消息处理函数发送过去,而不会发送wm_keydown消息
 
 

第十课

一目录操作
1.1得到当前工作目录
DWORD GetCurrentDirectoy(DWORD nBULength,LPTSTR buf)
1.2.设置当前工作目录
BOOL SetCurrentDirectory(LPCTSTR NewPathName);
1.3得到windows目录
UINT GetWindowsDirectory(LPTSTR buff,UINT size);
1.4.得到system目录
GetSystemDirectoy(LPTSTR buffer ,UINT size);
1.5.得到temp目录
GetTempPath(DWORD buffLength, LPTSTR buffer);

二.文件操作
2.1打开文件
HANDLE CreateFile(LPCTSTR FileName文件名称,
DWORD access访问权限 ,
DWORD shareMode共享方式,
NULL安全属性,
DWORD CreateDiposition创建方式,
DWORD flags文件属性,
NULL文件句柄模板)
2.1.1访问权限
GENERIC_READ 可读权限
GENERIC_WRITE 可写权限
GENERIC_EXECUTE 执行权限
GENERIC_ALL 所有权限
2.1.2创建方式:
CREATE_NEW 创建文件;如文件存在则会出错
   CREATE_ALWAYS 创建文件,会改写前一个文件
   OPEN_EXISTING 文件必须已经存在。由设备提出要求
   OPEN_ALWAYS 如文件不存在则创建它
2.1.3文件属性
FILE_ATTRIBUTE_NORMAL 默认属性
  FILE_ATTRIBUTE_HIDDEN 隐藏文件或目录
  FILE_ATTRIBUTE_READONLY 文件为只读
  FILE_ATTRIBUTE_SYSTEM 文件为系统文件
2.1.4返回值
Long,如执行成功,则返回文件句柄
失败INVALID_HANDLE_VALUE无效句柄
2.2写入文件:
BOOL WriteFile(HANDLE hFile文件句柄,
LPCVOID buffer数据,
DWORD numberOfWrite数据长度,
LPDWORD numberOfBytesWriten实际写入长度,
NULL)
2.3读取文件
BOOL ReadFile(HANDLE buffer 文件句柄 ,
DWORD bytesRead数据buf,
LPDWORD lpNumberOfBytesRead要读取个数,
LPDWORD lpNumberOfBytesRead实际读取,
NULL默认)
2.4关闭文件
BOOL CloseHandle(HANDLE hObject)
2.5 得文件大小
DWORD GetFileSize(HANDLE hFile文件句柄,
LPDWORD lpfileSizeHigh文件长度的高32位),
返回文件长度低32位
2.6文件指针偏移
DWORD SetFilePointer(HANDLE hFile文件句柄,
LONG move偏移量低32位,
PLONG high偏移高32位,
DWORD method偏移相对位置)
2.7拷贝文件
CopyFile(源文件地址,目的文件地址,是否存在就失败)
//前两个分别表示源文件和目标文件,第三个表示当目标文件存在时的处理,FASLE表示覆盖目标文件
2.8删除文件
DeleteFile(删除文件的文件名)
2.9移动文件
MoveFile(目的路径,源路径)

三.文件查找
HANDLE FindFirstFile(LPCTSTR name, LPWIN32_FIND_DATA fileFileData);
BOOL FindNextFile(HANDLE findFile,LPWIN32_FIND_DATA findData)
BOOL FindClose(HANDLE findFile)
 
 

第十一课

一.文件映射步骤
1.1打开或创建文件
CreateFile()
1.2创建内存映射
HANDLE CreateFileMapping(文件句柄,安全属性,访问方式,
文件大小的高32= 0,文件大小的低32,映射命名)
1.3加载内存映射文件
LPVOID MapViewOfFile(内存映射句柄,访问模式,偏移量高32,
偏移量低32,映射字节数)
1.4 卸载映射
UnmapViewOfFile(卸载地址)
1.5关闭句柄
CloseHandle();//关闭映射句柄 以及文件
二.打开文件映射
2.1读取文件内容
HANDLE OpenFileMapping( //返回
DWORD               dwDesiredAccess,    // 指定保护类型
BOOL                  bIsInheritHandle,     // 返回的句柄是否可以被继承
LPCSTR                lpName             // 创建对象时使用的名字
2.2加载内存映射文件
LPVOID MapViewOfFile(内存映射句柄,访问模式,偏移量高32,
偏移量低32,映射字节数)
案例:
HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "DANNY" );
    CHAR *ps = (CHAR*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS,0, 64*1024, 0 );
    printf( "%s\n", ps );
    UnmapViewOfFile( ps );
    CloseHandle( hMap );
HANDLE hFile = CreateFile( "c:/map.dat",GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
    HANDLE hMap = CreateFileMapping( hFile, NULL,PAGE_READWRITE, 0, 1024*1024, "DANNY" );
    CHAR *pszText = (CHAR*)MapViewOfFile( hMap, FILE_MAP_ALL_ACCESS, 0, 64*1024, 0 );
    strcpy( pszText, "ABCD" );
    printf( "%s\n", pszText );
    UnmapViewOfFile( pszText );
    getchar( );
    CloseHandle( hMap );//一旦关闭,就没了
    CloseHandle( hFile );
    return 0;
 
 

第十二课

一.Windows内存地址空间
    程序中可以寻址的最大范围。对于程序的运行效率就更高。对于32位操作系统,地址空间范围为0-4G(2^32)
二 地址空间的划分
    2.1 用户地址空间
0 - 2G(7FFFFFFF )存放用户的程序和数据。用户空间不能访问内核空间
     2.1.1 空指针区(NULL区,0-64K)系统将地址小于64K指针,都是空指针。为了帮助程序员掌握NULL指针的分配情况
     2.1.2 用户区
     2.1.3 64K禁入区(0x7FFEFFFF - 0x7F FFFFFF )隔离了用户和内核空间;防止用户程序跨越到内核空间中
    2.2 内核地址空间
2G - 4G 存放内核的代码和数据,例如系统驱动。
内核空间代码是可以访问用户空间。
三. Windows 内存
3.1 区域
    区域就是连续的一块内存。区域的大小一般为64K或者64K倍数。每个区域都有自己的状态:
    1)空闲:没有被使用
    2)私有:被预定的区域
    3)映像:存放代码
    4)映射:存放数据
3.2内存
    物理内存:系统可以使用的实际内存。CPU可以直接访问的内存。
3.2.1虚拟内存
    将硬盘文件虚拟成内存使用。(pagefile.sys 文件)
    CPU如果要访问虚拟内存数据,必须将虚拟内存数据    放到物理内存内存页
    系统管理内存的最小单位。内存页大小为4K,每个内存页有自己的权限。
3.2.2内存获取数据过程
1.根据地址在物理内存中查找相应的位置。如果找到物理内存,取回数据。如果未找到,执行下一步
2.根据地址去虚拟内存中查找相应的位置。如果未找到,那么该地址没有内存空间,返回错误。如果找到,执行下一步
3 将该地址所在内存页,置换到物理内存中,同时将原物理内存数据,存入到虚拟内存中。然后将物理内存中的数据返回给使用者。 
四.内存信息结构体
MEMORYSTATUS结构体用来存储虚拟内存的详细信息
dwLength
MEMORYSTATUS结构的大小,sizeof()函数求得,用来供函数检测结构的版本。
dwMemoryLoad
返回一个介于0~100之间的值,用来指示当前系统内存的使用率。
dwTotalPhys
返回总的物理内存大小,以字节(byte)为单位。
dwAvailPhys
返回可用的物理内存大小,以字节(byte)为单位。
dwTotalPageFile
显示可以存在页面文件中的字节数。
注意这个数值并不表示在页面文件在磁盘上的真实物理大小。
dwAvailPageFile
返回可用的页面文件大小,以字节(byte)为单位。
dwTotalVirtual
返回调用进程的用户模式部分的全部可用虚拟地址空间,以字节(byte)为单位。
dwAvailVirtual
调用进程的用户模式部分的实际自由可用的虚拟地址空间,字节(byte)为单位。
函数使用-----GlobalMemoryStatus(),用来获取内存信息
五.虚拟内存分配
5.1虚拟内存分配
速度快,大内存效率高。将内存和地址分配分别执行
可以在需要的时候再提交内存。常用字大型电子表格等处理。
5.2虚拟内存使用
    5.2.1 内存分配(申请地址/提交内存)
     LPVOID VirtualAlloc(
        LPVOID lpAddress,// NULL或提交地址
        SIZE_T dwSize, //分配的大小
        DWORD flAllocationType, //分配方式
        DWORD flProtect //内存访问方式 PAGE_READWRITE ); 分配成功返回地址
5.2.2分配方式:
    MEM_COMMIT - 提交内存,分配之后返回地址和内存空间连
   MEM_RESERVE- (预约)保留地址,分配之后只返回地址,内存空间不生成。
要使用内存必须再次提交。只要 地址 不要 内存
使用:直接按照内存处理方式。
5.2.3 虚拟内存释放
VirtualFree(
LPVOID lpAddress,//释放地址
SIZE_T dwSize,//释放大小
DWORD dwFreeType//释放方式);
5.2.4释放方式
MEM_DECOMMIT - 只释放内存,不释放地址
    MEM_RELEASE - 连 地址 带 内存 都释放
六.堆内存
程序会有默认堆内存,我们可以在内存地址空间创建额外的堆
创建堆内存目的:默认堆堆数据进行混合存储,效率低下。
申请可以更有效的使用内存,避免现充同步开销。快速释放
6.1获取堆数据
DWORD GetProcessHeaps(
NumberOfHeaps, //堆数组大小
PHANDLE ProcessHeaps //堆句柄
);//返回堆个数
GetProcessHeap()----获取程序所有的堆
6.2创建堆
HeapCreate(
DWORD flOptions,//创建选项 0
SIZE_T dwInitialSize,//初始化大小
SIZE_T dwMaximumSize//最大值);成功返回堆句柄
最大值:如果最大值是0.则堆是可以增长的,没有指定的上限.
6.3堆内存分配
LPVOID HeapAlloc(
HANDLE hHeap,//堆句柄
DWORD dwFlags,//分配方式
SIZE_T dwBytes//分配大小);//返回申请的内存首地址
6.4释放堆内存
BOOL HeapFree(
HANDLE hHeap,//堆句柄
DWORD dwFlags,//释放标志
LPVOID lpMem//释放地址);
6.5销毁堆
BOOL HeapDestroy( HANDLE hHeap);
 
 

第十三课

一.进程
1.1进程定义
进程是一个容器,包含程序执行需要的代码、数据、资源等等信息。Windows是多任务操作系统,可以同时执行多个进程。
1.2.Windows进程的特点
1)每个进程都有自己的ID号
2)每个进程都有自己的地址空间,进程之间无法访问对方的地址空间。
3)每个进程都有自己的安全属性
4)每个进程当中至少包含一个线程
1.3.进程的id和句柄
获取当前进程ID: DWORD GetCurrentProcessId()
得到当前进程的句柄: HANDLE GetCurrentProcess( VOID );
为了安全,返回一个假的句柄,但可以直接使用假的句柄操作当前线程
1.4创建进程
BOOL CreateProcess(
    LPCWSTR lpApplicationName,//进程路径
    LPWSTR lpCommandLine,//命令行参数
    LPSECURITY_ATTRIBUTES lpP,//进程安全属性
    LPSECURITY_ATTRIBUTES Attribu,//线程安全属性
    BOOL bInheritHandles,//进程的句柄继承
    DWORD dwCreationFlags,//创建方式
    LPVOID lpEnvironment,//环境信息
    LPCWSTR lpCurrentDirectory,//当前目录
    LPSTARTUPINFOW lpStartupInfo,//起始信息
    LPPROCESS_INFORMATION lp//进程句柄(传出)
);
1.5等待进程结束
WaitForSingleObject( 进程句柄, INFINITE );
1.6打开线程—得到进程句柄
HANDLE OpenProcess(
DWORD dwDesiredAccess,//打开权限PROCESS_ALL_ACCESS
BOOL bInheritHandle,//继承方式
DWORD dwProcessId//进程id );
1.7结束当前进程
Void ExitProcess(UINT uExitCode退出码);
1.8结束指定进程
TerminateProcess(进程句柄,退出码)
二. 线程
2.1 线程定义
windows以线程为单位进行调度程序,一个程序中至少有一个线程
可以有多个线程,用来实现多任务的处理
2.2线程特点
线程都有一个id
线程都具有自己的安全属性
线程都有自己的内存栈
线程都有自己的寄存器信息
2.3创建线程:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpT,//安全属性
SIZE_T dwStackSize,//线程栈大小
LPTHREAD_START_ROUTINE lp,//线程处理函数
LPVOID lpParameter,//处理函数参数
DWORD dwCreationFlags,//创建方式
LPDWORD lpThreadId//线程id );//线程句柄
创建标志:0---创建后立刻执行
CREATE_SUSPENDED-创建之后线程处于挂起
2.4线程处理函数
DWORD WINAPI Threadproc(LPVOID lp){ 参数是需要传入的}
2.5结束线程
BOOL TerminateThread(
HANDLE hThread,//线程句柄
DWORD dwExitCode//退出码);
结束当前线程
VOID ExitThread(DWORD dwExitCode退出码)
关闭线程句柄:closeHandle
2.6等候进程结束
DWORD WaitForSingleObject(
HANDLE hHandle, //句柄
DWORD dwMilliseconds//等时间);
DWORD WaitForMultipleObjects(
DWORD nCount,//句柄数量
HANDLE *lpHandles,//句柄地址
BOOL bWaitAll,//等方式
DWORD dwMilliseconds//等时间 );
等待方式:TRUE---所有句柄有信号才结束
FALSE---一个句柄有信号就返回
三.线程同步
3.1原子锁
对单条指令进行操作,当多个线程同时对同一个资源进行操作的时,由于线程间资源的抢占,会导致操作的结果丢失或者不是我们预期的。例如a++
interLockedIncrement、加
interlockedDecrement减
InterlockedExchange交换
3.2临界区
CRITICAL_SECTION cs = { 0 };
InitializeCriticalSection() //
EnterCriticalSection( &cs );
LeaveCriticalSection( &cs );
DeleteCriticalSection( &cs );
3.3事件
3创建事件:
HANDLE CreateEvent(
LPSECURIT utes,// 安全属性
BOOL bManualReset,//重置方式false自动 true手动
BOOL bInitialState,//初始状态ture有信号
LPCSTR lpName//事件名
);成功返回事件句柄
等候事件 waitforsingleobject/xxxMultiple
触发事件: setEvent(事件句柄)
resetEvent()
关闭事件CloseHandle
3.4 互斥
HANDLE CreateMutex(
LPSECURITY_A butes,//安全属性
BOOL bInitialOwner,//初始拥有者
LPCSTR lpName//互斥命名);
拥有者:调用createMtex的拥有互斥
False 创建的时候没有线程拥有互斥
等候互斥 WaitForSingleObject
释放互斥ReleaseMutex(互斥量)
关闭句柄 closehandle
3.5 信号量
3.5.1创建信号量
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSees,//安全属性
LONG lInitialCount,//初始化信号量数量
LONG lMaximumCount,//信号量最大值
LPCSTR lpName//命名);
等候信号量:等候通过一次 信号量的信号减一,0堵塞
3.5.2释放信号量
BOOL ReleaseSemaphore(
HANDLE hSemaphore,//信号量句柄
LONG lReleaseCount,//释放数量
LPLONG lpPreviousCount//释放前数量 );
关闭句柄+
 
 
 

第十四课

一.库文件介绍
静态库:库中代码被链接到可执行程序或动态库中,运行时不需要。扩展名为.lib
动态库:库中代码不被链接到可执行程序或其它动态库中,运行时需要且为多个使用者共享。扩展名为.dll。
二.创建静态库
1.创建win32静态库工程,写函数
2. 链接静态库
1) 代码中加入#pragma comment (lib, "../Lib/CLib.lib")
2) 通过Project/Settings...设置,添加../Lib/CLib.lib
注意:默认情况下C++编译器会做函数换名,extern "C"抑制C++编译器做函数换名。
三.动态库静态库比较
1) 由于静态库是将代码嵌入到使用程序中,多个程序使用时,会有多份代码,所以代码体积会增大。动态库代码只需要一份,其它程序通过函数地址以共享方式使用动态库中的代码,所以体积小。
2) 静态库发生变化后,新的代码需要重新链接(嵌入)到使用程序中。
四.函数导出
方式一:
声明导出:函数声明前加_declspec (dllexport)前缀,若无声明则加在定义之前。
方式二:
模块定义文件导出:.def
LIBRARY CDll
EXPORTS
c_add @1
c_sub @2
注意:动态库也会生成.lib(导入库),但其内容与静态库完全不同。
导入库中只存放函数名与函数序号(Ordinal)的映射表。
链接器在链接阶段,根据此映射表,为该动态库的使用者,
生成由函数序号定位函数入口(Entry Point)的代码。
四:加载方式
4.1静态加载
1) 链接导入库(.lib),声明为导入_declspec (dllimport)。
2) 动态库需要放在如下位置:
A. 可执行程序所在目录 -- 推荐使用
B. 当前工程目录 -- 依赖于开发环境,调试时使用
C. WINDOWS目录 或 ystem32目录 或WINDOWS/system目录 /
3) 可执行程序启动时加载动态库,退出时卸载动态库。
4.2 动态加载
1) 定义函数指针类型:typedef ...
2) 加载动态库
HMODULE LoadLibrary (
LPCTSTR lpFileName // 动态库文件名(按路径规则搜索)
// 或绝对/相对路径(按指定路径加载)
); 成功返回动态库实例句柄(HINSTANCE),失败返回NULL。
3) 获取函数地址
FARPROC GetProcAddress (
HMODULE hModule, // 动态库实例句柄
LPCSTR lpProcName, // 函数名(注意C++换名问题));
成功返回函数地址,失败返回NULL。
4) 卸载动态库
BOOL FreeLibrary (//成功返回TRUE,失败返回FALSE。
HMODULE hModule // 动态库实例句柄);
五.动态库中导出类
编库时声明为导出,用库时声明为导入。
#ifdef CPPDLL_EXPORTS
#define CPPDLL_API _declspec (dllexport)
#else
#define CPPDLL_API _declspec (dllimport)
#endif /* CPPDLL_EXPORTS */
class CPPDLL_API CMath{...};
五. 入口函数
入口函数不是动态库所必须的,常用于动态库内部的初始化和善后处理。
BOOL WINAPI DllMain (
HANDLE hinstDLL, // 动态库实例句柄
DWORD dwReason, // 被调用的原因
LPVOID lpvReserved // 保留);
返回TRUE表示动态库加载成功,FALSE表示失败。
动态库加载/卸载时会被调用。如:LoadLibrary/FreeLibrary。
dwReason取值:
DLL_PROCESS_ATTACH - 进程加载,在主线程中调用LoadLibrary
DLL_PROCESS_DETACH - 进程卸载,在主线程中调用FreeLibrary
DLL_THREAD_ATTACH - 线程加载,在子线程中调用LoadLibrary
DLL_THREAD_DETACH - 线程卸载,在子线程中调用FreeLibrary

win32笔记

原文:https://www.cnblogs.com/MessiXiaoMo3334/p/9513708.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!