创建完后设置为启动项目
有入口 --> 可执行 --> 程序的最终文件可以进内存
没有入口 --> 无法执行
在解决方案中添加一个新项目 -》动态库程序
CL.EXE 和 LINK.EXE 可执行程序 在安装的路径下的 VC下bin
(kernel32.dll, user32.dll, gdi32.dll 三个动态库的路径) 在 C:\Windows\System32 下
(几个重要的头文件所在的路径) C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include
窗口程序入口函数
句柄:
是一个用来找到内存的东西,但绝对不是指针
提示框
#include
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|
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
参考代码:
#include
//窗口处理函数(自定义,处理消息)
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;
}
ASC - 7位代表一个字符 128个字符
ASCII - 美国国家信息标准交换码(扩展ASC码) 8位代码一个字符,256个字符
MBCS - 多字节字符编码
DBCS - 单双字节混合编码(没有统一标准) 例 A 01 我 0203 是 0405 程 0607 序 0809 源0A0B
UNICODE -万国码
utf-8 : unix 系统
utf-16: 所有字符统统按照两个字节来编码
//#define UNICODE
#include
#include
#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宏的定义)
#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
#include
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;
}
参考代码:
#include
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;
}
#include
#include
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
#include
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;
}
参考代码: winMsg.cpp
// 定义自定义消息
#define WM_MYMESSAGE WM_USER + 1001
#include
#include
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;
}
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);
}
参考代码:
#include
#include
HINSTANCE g_hInstance = 0;// 当前程序实例句柄
HANDLE g_hOutput = 0;
int g_xPos = 100,g_yPos = 100;
void OnKeyDown