Windows程序设计1(工具、编码、窗口)
一、几个常用小工具:
1. 编译器:CL.EXE 将源文件转变为目标文件(汇编语言)。
CL.EXE /c xxx.c 或 xx.cpp
cl.exe -? 显示cl帮助
cl.exe /c 只编译不链接
cl.exe /Tc 编译c文件
cl.exe /l 头文件路径
链接器:LINK.EXE 将目标文件转变为二进制文件(机器语言)。
LINK.EXE xxx.obj user32.lib xxx.lib等需要的相关库文件(link.exe ***.obj ***.lib)
资源编译器:RC.EXE 将资源(**.rc)编译(**.res),最终通过链接器存入最终文件(.rc资源脚本文件)。
执行: ***.exe
2、设置控制台的输出代码页:
BOOL SetConsoleOutputCP(UINT wCodePageID);//代码页ID,936中文,437英文。
若不设置,ascII 将后面128个无法正常显示,正常显示前128个。
编码方式:四种:ASC码、ASCII码,DBCS码、UNICODE码
wchar_t 宽字节字符,每个字符占两个字节,实际上是unsigned short 类型,定义时候需要在前面加:”L”,告知编译器按照双字节编译字符串.采用UNICODE编码,而char占用一个字节。
如:wchar_t *pwszText=L”hello wchar_t !”;
wpritf(L”%s\n”,pwszText) ;
///不可用printf,求字节长度:wcslen(pwszText);不可用strlen();
另外使用时,定义: #define UNICODE 应放在尽量的在最前面,防止在其他头文件不起作用。
wprintf()对UNICODE支持不是很完善,可通过下面更好的控制台输出
BOOL WriteConsole(
HANDLE hConsoleOutput, //标准输出句柄
CONST VOID *lpBuffer, // 输出内容的buffer
DWORD nNumberOfCharsToWrite, // 输出内容的长度
LPDWORD lpNumberOfCharsWritten, // 返回实际输出的内容长度
LPVOID lpReserved // 备用
);
操作系统已经预备了三个句柄:标准输出句柄、标准输入句柄、标准错误句柄。GetStdHandle()可返回获取这三种句柄。
二、NMAKE和Makefile
1. nmake为一个解释执行的工具,根据makefile文件的定义,编译和链接程序,最终生成目标文件。
2. makefile定义编译和链接等操作的脚本文件(把项目的处理命令写入)(以**.mak为后缀的文件),一般对整个向项目进行处理。
Makefile语法:
HELLO:依赖行 ////可以有多个依赖行
//依赖行如下3行
cl.exe /c hello.c ///命令行
rc.exe hello.rc ///命令行
link.exe hello.obj hello.res user32.lib ///命令行
其执行方式:
1.首先找到第一个依赖行。
2.检查依赖行的依赖项,若发现依赖项,则先执行依赖项的命令行。
3.执行完所有的依赖项命令后,再执行自己的命令行。
A:B
5**.** **
6**.** **
B:C
3**.** **
4**.** **
C:
1**.** **
2**.** **
则执行顺序:C->B->A。也即:(1->2->3......->6)
如:(HELLO与CLEAN是标识而已,一般大写)
HELLO:
cl.exe /c my.cpp
rc.exe my.rc
link.exe my.obj my.res user32.lib
CLEAN:
del *.obj
del *.res
执行:nmake /f **.mak CLEAN
若果没有加/f 和CLEAN ,则只会执行HELLO的。
改进:
CLEAN:HELLO
del *.obj
del *.res
HELLO:
cl.exe /c my.cpp
rc.exe my.rc
link.exe my.obj my.res user32.lib
///先执行CLEAN,发现依赖项HELLO,在执行HELLO的依赖项目。
///最后CLEAN再执行自己的依赖项目
三、Windows下的库与头文件
库: kernel32.dll 提供核心的API:线程、进程、内存管理等。
user32.dll 提供了窗口、消息等API。
gdi32.dll 绘图相关的API。
头文件:windows.h 所有windows头文件的集合(使用时包含此头文件,即可包含以下头文件,除winnt.h)。
windef.h windows数据类型。
winbase.h kernel32的API。
wingdi.h gdi32的API。
winuser.h user32的API 。
winnt.h UNICODE字符集支持。
四、Windows程序设计基础
(HINSTANCE)句柄:用来找到内存,但是句柄绝对不是指针。
入口函数:
int WINAPI WinMain(
HINSTANCE hInstance,//当前程序的实例句柄
HINSTANCE hPrevInstance,//当前程序前一个实例句柄。现在为无用的参数。兼容而已。
LPSTR lpCmdLine,//命令行参数字符串
int nCmdShow,//窗口显示方式。
);
消息框:
int MessageBox(
HWND hWnd,//父窗口句柄
LPCTSTR lpText,//显示消息框中的文字
LPCTSTR lpCaption,//显示在消息框标题栏上的文字
UINT uType///消息框中图标按钮类型风格
);///返回点击的按钮的ID
窗口程序的编写步骤:
1 定义WinMain()入口函数
2 定义窗口处理函数WindowProc()。(处理消息)
3 注册窗口类WNDCLASS wndclass。RegisterClass(&wndclass),注册到操作系统
4 创建窗口CreateWindow()。(只是创建到内存的数据,并没绘制)
5 显示窗口ShowWindow() / UpdateWindow()
6 消息循环(GetMessage()提取消息、TranslateMessage()翻译消息、DispatchMessage()派发消息)。
7 消息处理
窗口类包含了窗口的各种参数信息的数据结构。每个窗口都具有窗口类,基于窗口类创建窗口。每个窗口类都具有一个名称,使用前必须注册到系统。
窗口类分为三类:系统窗口类、应用程序全局窗口类、应用程序局部窗口类。
特点分别为:系统已经定义好的窗口类,所有应用程序都可以直接使用,不需要注册,如:按钮 BUTTON,编辑框 EDIT,它们的类名就是BUTTON、EDIT等。由用户自己定义,当前应用程序所有子进程
模块都可以使用它,注册窗口类型在窗口类风格中增加:wndclass.style=CS_GLOBALCLASS|**|**,也会使得程序的开发、使用维护,错误检测变得困难。
由用户自己定义,当前应用程序中本进程模块可以使用它,不加风格CS_GLOBALCLASS。
窗口类的查找过程:
1.系统根据传入的窗口类名称,在应用程序局部窗口类中查找,若找到执行2.否则执行3。
2.比较局部窗口类与创建窗口时传入的HINSTANCE变量,如发现相等,创建和注册的窗口类在同一模块(进程),创建窗口返回。否则继续执行3。
3.在应用程序全局窗口类,(此时不用再匹配HINSTANCE变量了)若找到执行4.否则执行5。
4.使用找到的窗口类的信息,创建窗口并返回。
5.在系统窗口类中查找,若找到创建窗口返回,否则创建窗口失败。
(因此,在创建窗口时,速度上:创建局部窗口>创建全局窗口>创建系统窗口)
子窗口的创建:
1.创建时要设置父窗口的句柄。
2.创建风格要增加WS_CHILD|WS_VISIBLE。
窗口类的风格:
CS_GLOBALCLASS - 应用程序全局窗口类
CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8倍数对齐
CS_BYTEALIGNWINDOW - 窗口的水平位置8倍数对齐
CS_HREDRAW - 当窗口水平变化时,窗口重新绘制
CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制
CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备
CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备
CS_OWNDC - 该类型的窗口,每个窗口都使用自己的绘图(DC)设备
CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源
CS_DBLCLKS - 允许窗口接收鼠标左键双击
CS_NOCLOSE - 窗口没有关闭按钮
GetClassInfo / GetClassInfoEx 获取窗口类信息。
ShowWindow(hWnd ,…)
{
- 根据hWnd,找到窗口信息的那块内存。
- 再根据内存储存的关于窗口的各项信息,绘制窗口。
}
五、第一个Win 32 程序
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam , LPARAM lParam)//处理消息函数
{
return DefWindowProc(hWnd,uMsg,wParam,lParam); //自动处理许多消息
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
static TCHAR szAppName[]=TEXT("WINNT"); //TEXT为宏,非函数
HWND hWnd;// 创建窗口句柄
MSG msg;//消息结构体
WNDCLASS wndclass;
wndclass.style=CS_HREDRAW|CS_VREDRAW;// 窗口类风格,水平或垂直移动刷新窗口,
wndclass.lpfnWndProc=(WNDPROC)WndProc; //回调函数指针
wndclass.cbClsExtra=0; //窗口类附加数据大小
wndclass.cbWndExtra=0; //窗口附加数据大小
wndclass.hInstance=hInstance; //当前模块的实例句柄
wndclass.hIcon=NULL; //窗口图标句柄
wndclass.hCursor=NULL; //鼠标光标句柄
wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); //窗口背景画刷
wndclass.lpszMenuName=NULL; //窗口菜单的资源ID字符串
wndclass.lpszClassName=szAppName;//窗口类的名称
RegisterClass(&wndclass);//将所有信息注册到操作系统
///卸载:UnregisterClass(szAppName, hInstance);
hWnd=CreateWindow(
szAppName,//注册的窗口类名
TEXT("第一个win32程序!"),//窗口标签
WS_OVERLAPPEDWINDOW,//窗口风格具有水平与垂直滚动条
100,//x的起点
100,//y的起点
500,//窗口的高度
500,//窗口的宽度
NULL,//父窗口句柄
NULL,//菜单或子窗口句柄
hInstance,//应用程序实例句柄
NULL///附加数据
);
ShowWindow(hWnd,SW_SHOW); //创建成功则显示窗口
UpdateWindow(hWnd); ///送出WM_PAINT消息
while(GetMessage(&msg,NULL,0,0))//消息循环,获取消息
{
TranslateMessage (&msg); //检索消息,转化消息
DispatchMessage (&msg); //将消息间接传给函数指针,传回给窗口函数(回调函数)
}
return msg.wParam; ///从PostQuitMessage返回的值.PostQuitMessage(0)结束消息循环
}
六、窗口类的使用
定义数据空间的大小(在WNDCLASSEX结构体中):int cbClsExtra; //一般定义为4字节的倍数(0,4,8,….)(若为100,则索引号只能最多为96,若200,则196,由于新值为long,至索引号后剩下的要留足4个字节空间)。
重存入数据:
DWORD SetClassLong(
HWND hWnd, //窗口句柄,
int nIndex, //字节索引号,也取4字节地整数倍
LONG dwNewLong //////新的数据值。指针变量也可以
);//返回原数据值
读取数据:
DWORD GetClassLong(
HWND hWnd, ///窗口句柄
int nIndex ////字节索引号
);//返回获取值
七、窗口使用
定义数据空间大小:int cbWndExtra;///同样一般定义为4字节的整数倍;
重存入数据:
LONG SetWindowLong(
HWND hWnd, ///窗口句柄
int nIndex, ///设置补偿值
LONG dwNewLong //////新的数据值
);//返回先前的数据值
读取数据:
LONG GetWindowLong(
HWND hWnd, //窗口句柄
int nIndex //取回补偿值
);
窗口类附加数据与窗口附加数据区别:
前者的附加数据提供的BUFF,是所有该类窗口共享的BUFF,后者的附加数据提供的BUFF,值属于该窗口所拥有,是窗口私有的BUFF。
八、MDI (多文档)窗口创建
- 1 创建主窗口
- 没有父窗口,需要注册窗口类。
-在主窗口的窗口处理函数中,调用MDI主窗口的缺省处理函数DefFrameProc,不调用DefWindowProc函数。
- 2 创建“MDICLIENT”窗口
-父窗口是主窗口,窗口类为“MDICLIENT”
-创建时,要使用创建参数CLIENTCREATESTRUCT 定义子窗口的起始ID
- 3 创建子窗口
-子窗口的父窗口是“MDICLIENT”窗口,需要注册窗口类。
-子窗口的窗口处理函数缺省调用DefMDIChildProc。
Windows程序设计1(工具、编码、窗口)的更多相关文章
- Windows程序设计--(三)窗口与消息
3.1 窗口的创建 3.1.1 系统结构概述 所谓「Windows给程序发送消息」,是指Windows呼叫程序中的一个函数,该函数的参数描述了这个特定消息.这种位于Windows程序中的函数称为「窗口 ...
- windows程序设计01_utf8编码问题
坚持与妥协 从学程序的第一天老师就给我们说源代码应该使用utf8保存.因为先入为主,"源代码应该使用utf8"的观念已经在"学院派"出身的程序员脑子里根深蒂固. ...
- windows gui测试工具:AutoIt
windows gui测试工具:AutoIt 2017-01-09 目录 1 简介2 示例1 记事本自动化操作3 示例2 上传文件 1 简介 返回 AutoIt v3 是用以编写并生成具有 BASIC ...
- Windows程序设计:格式化对话框的设计
刚开始学习Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,主要是将MessageBox这个Windows API函数的. MessageBox函数是许多人刚开始学习Windows程序设计或者是 ...
- Windows 程序设计 笔记
知识点 双字节字符集和Unicode字符集有何区别?采用双字节字符集有何问题 双字节字符集(DBCS)编码是0-255,DBCS含有1字节代码与2字节代码,而Unicode是统一的16位系统,这样就允 ...
- Windows 程序设计(4) MFC 03 -系列学习
本文整体目录和绝大部门内容来自 [鸡啄米网站]的MFC系列文章,欢迎支持原创 (一)VS2010/MFC编程入门之前言 VC++全称是Visual C++,是由微软提供的C++开发工具,它与C++的根 ...
- Windows 程序设计
一.Win32 API /******************************************************************** created: 2014/04/1 ...
- windows 程序设计自学:添加图标资源
#include <windows.h> #include "resource.h" LRESULT CALLBACK MyWndProc( HWND hwnd, // ...
- 《Windows程序设计第5版》学习进度备忘
书签:另外跳过的内容有待跟进 __________________学习资源: <Windows程序设计第5版珍藏版> __________________知识基础支持: _________ ...
随机推荐
- java -- 虚拟机和内存
从大方向来分:栈内存,堆内存,方法区,本地方法栈,程序计数器 java从存储数据的角度来分: 寄存器(register):最快的存储区,由编译器根据需求进行分配,不由认为控制. 堆栈(statck): ...
- 【USACO 2857】 Steady Cow Assignment
[题目链接] 点击打开链接 [算法] 二分答案,check的时候跑最大流,即可 [代码] #include<bits/stdc++.h> using namespace std; #def ...
- Bootstrap-CSS:排版
ylbtech-Bootstrap-CSS:排版 1.返回顶部 1. Bootstrap 排版 Bootstrap 使用 Helvetica Neue. Helvetica. Arial 和 sans ...
- label标签的可访问性
与表单元素关联的方法(IE6下label标签包裹控件的方法是不顶用的): 1 使用for和id关联控件 <p><label for="test">标签< ...
- Python2/3共存,pip2/3共存
python2 和 python3设置: 1.安装Python2和3,并添加环境变量: 2.找到python2和python3的安装目录,修改python2中和python3中python.exe和p ...
- E20180331-hm
corresponding adj. 相当的,对应的; 通信的; 符合的,符合; 一致的; implicitly adv. 含蓄地; 暗示地; 无疑问地; 无保留地; causal adj. 具有因 ...
- Thrift 入门
1下载 https://thrift.apache.org/download 或 Apache Thrift Archive 下载编译好的release可执行文件: Thrift compiler f ...
- bzoj 4622: [NOI 2003] 智破连环阵【dfs+匈牙利算法】
一个炸弹炸一个区间的武器,想到二分图匹配 但是直接dfs断点显然不行,预处理出dis[i]为i到m的至多值来最优性剪枝,并且标记ok[i][j]为炸弹i可以炸到j武器,mx[i][j]为i炸弹从j武器 ...
- iOS音频与视频的开发(二)- 使用AVAudioRecorder进行录制音频
1.使用AVAudioRecorder录制视频 AVAudioRecorder与AVAudioPlayer类似,它们都属于AVFoundation的类.AVAudioRecorder的功能类似于一个录 ...
- (六)SpringBoot整合Swagger2框架
一:什么是Swagger Swagger是一款通过我们添加的注解来对方法进行说明,来自动生成项目的在线api接口文档的web服务. 二:添加Swagger2依赖 <dependency> ...