《Windows核心编程》读书笔记零 构建环境
来源:互联网 发布:java cova spank bang 编辑:程序博客网 时间:2024/06/07 01:26
Solution配置
建立一个Solution将每个project加入此Solution
确保输出目录在同一个目录下
C/C++ ->Code Generation -> Runtime Library 选择多线程的版本
C/C++ 检测64位可移植性 (/Wp64) 在VS2013中此选项已经移除。想启用此选项需要自行增加命令行参数 WP64 在VS2013中32位应用已经不再支持此选项。
CmnHdr.h头文件
包含宏定义,链接参数等。
Microsoft Windows Version 构建选项
_WIN32_WINNT 和 WINVER = 0x600 表示windows VISTA
// = 0x0600 for VISTA level from sdkddkver.h#define _WIN32_WINNT _WIN32_WINNT_LONGHORN #define WINVER _WIN32_WINNT_LONGHORN
因为在VISTA中 CreateMutexExW 需要windows版本在Vista以上才支持
#if (_WIN32_WINNT >= 0x0600)#pragma region Application Family#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)#define CREATE_MUTEX_INITIAL_OWNER 0x00000001WINBASEAPI_Ret_maybenull_HANDLEWINAPICreateMutexExA( _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, _In_opt_ LPCSTR lpName, _In_ DWORD dwFlags, _In_ DWORD dwDesiredAccess );WINBASEAPI_Ret_maybenull_HANDLEWINAPICreateMutexExW( _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, _In_opt_ LPCWSTR lpName, _In_ DWORD dwFlags, _In_ DWORD dwDesiredAccess );如果不加入此定义则会可能导致编译错误。
Unicode构建选项
默认开启Unicode
// Always compiler using Unicode.#ifndef UNICODE#define UNICODE#endif// When using Unicode Windows functions, use Unicode C-Runtime functions too.#ifdef UNICODE #ifndef _UNICODE #define _UNICODE #endif#endif
Windows Definitions与编译警告级别4
常用代码使用最高警告级别。
因为微软设计的Windows.h使用了很多对标准C的扩展,设置警告级别为3。
///////////////////////// Include Windows Definitions /////////////////////////#pragma warning(push, 3)#include <Windows.h>#pragma warning(pop) #pragma warning(push, 4)#include <CommCtrl.h>#include <process.h> // For _beginthreadex
pragma message 辅助宏
#pragma message("fix this later")
这样在编译时会提示一串文字,提醒我们在某个地方还有一些工作要做。
使用自定义宏
#pragma chMsg(Fix this later)
编译器会提示
1>------ Build started: Project: ErrorShow, Configuration: Debug Win32 ------1> ErrorShow.cpp1> c:\users\admin\documents\visual studio 2013\windowsviacpp\errorshow\errorshow\errorshow.cpp(19):fix this later1> ErrorShow.vcxproj -> C:\Users\admin\Documents\Visual Studio 2013\WindowsViaCPP\ErrorShow\Debug\ErrorShow.exe========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
chlNRANGE 宏
用于判断一个值是否处于两个值之间
// This macro returns TRUE if a number is between two others#define chINRANGE(low, Num, High) (((low) <= (Num)) && ((Num) <= (High)))
chBEGINTHREADEX宏
本书采用Microsoft C/C++的运行库 _beginthreadex来开启线程而不是windows系统函数CreateThread。
因为此beginthread运行C++运行库来初始化一个新线程,并且在线程返回时,为每一个新线程所分配的C/C++运行库信息快都能得到销毁
_beginthreadex定义
_CRTIMP uintptr_t __cdecl _beginthreadex( _In_opt_ void * _Security, _In_ unsigned _StackSize, _In_ unsigned (__stdcall * _StartAddress) (void *), _In_opt_ void * _ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned * _ThrdAddr);CreateThread定义
HANDLEWINAPICreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ __drv_aliasesMem LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId );
但是某些参数类型会使得编译器发出警告。比如unsigned 和 DWORD
返回值 long 和handle
因此cmmhdr定义了宏 chBEGINTHREADEX来进行相关数据的转换操作,防止编译器警告。
typedef unsigned (__stdcall *PTHREAD_START) (void *);#define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \ pvParam, dwCreateFlags, pdwThreadId) \ ((HANDLE)_beginthreadex( \ (void *) (psa), \ (unsigned) (cbStackSize), \ (PTHREAD_START) (pfnStartAddr), \ (void *) (pvParam), \ (unsigned) (dwCreateFlags), \ (unsigned *) (pdwThreadId)))
适用于x86平台的对DebugBreak的改进
某些情况下,即便进程不是通过调试器来启动的,我也希望它能按照我们的意愿停留在某一个断点。在Windows平台上,可以在一个线程调用DebugBreak函数来实现这个功能。这个kernel32.dll中的函数可以让我们attach一个调试器到进程。一旦attach到进程,指令指针(IP)就会停在那条激发断点的cpu指令。因为这条就是kernell32.dll中的DebugBreak指令,所以为了继续运行我们不得不在调试器中单步调试跳出DebugBreak函数
在x86处理器上,其实可以通过执行一条“int 3”使得cpu产生一个断点。作者通过内嵌int 3中断重新定义了一个DebugBreak函数。但执行DebugBreak的时候,系统并没有执行Kernell32.dll里的代码。这样单每次程序执行到断点的时候,CS:IP执像的就是DebugBreak的下一条代码。
////////////////// DebugBreak Improvement for x86 platforms ///////////////////#ifdef _X86_ #define DebugBreak() _asm { int 3 }#endif
创建软件异常码
使用MAKESOFTWAREEXCEPTION宏
/////////////////////////// Software Exception Macro //////////////////////////// Useful macro for creating your own software exception codes#define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) \ ((DWORD) ( \ /* Severity code */ (Severity ) | \ /* MS(0) or Cust(1) */ (1 << 29) | \ /* Reserved(0) */ (0 << 28) | \ /* Facility code */ (Facility << 16) | \ /* Exception code */ (Exception << 0)))
chMB宏
弹出一个消息框,消息框的标题是调用进程对应可执行文件的完整路径的名称。
/////////////////////////// Quick MessageBox Macro ////////////////////////////inline void chMB(PCSTR szMsg) { char szTitle[MAX_PATH]; GetModuleFileNameA(NULL, szTitle, _countof(szTitle)); MessageBoxA(GetActiveWindow(), szMsg, szTitle, MB_OK);}
chASSERT和chVERIFY宏
判断一个Assert断言。仅在Debug下有效
chVERIFY在debug和release下都有效。
//////////////////////////// Assert/Verify Macros /////////////////////////////inline void chFAIL(PSTR szMsg) { chMB(szMsg); DebugBreak();}// Put up an assertion failure message box.inline void chASSERTFAIL(LPCSTR file, int line, PCSTR expr) { char sz[2*MAX_PATH]; wsprintfA(sz, "File %s, line %d : %s", file, line, expr); chFAIL(sz);}// Put up a message box if an assertion fails in a debug build.#ifdef _DEBUG #define chASSERT(x) if (!(x)) chASSERTFAIL(__FILE__, __LINE__, #x)#else #define chASSERT(x)#endif// Assert in debug builds, but don't remove the code in retail builds.#ifdef _DEBUG #define chVERIFY(x) chASSERT(x)#else #define chVERIFY(x) (x)#endif
chHANDLE_DLGMSG宏
Message Cracker, 不应该使用HANDLE_MSG 因为其不会返回TRUE 或 FALSE
使用chHANDLE_DLGMSG能对消息的返回值进行处理,适用在对话框过程中调用。
/////////////////////////// chHANDLE_DLGMSG Macro /////////////////////////////// The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog// boxes because DlgProc returns a BOOL instead of an LRESULT (like// WndProcs). This chHANDLE_DLGMSG macro corrects the problem:#define chHANDLE_DLGMSG(hWnd, message, fn) \ case (message): return (SetDlgMsgResult(hWnd, uMsg, \ HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
chSETDLGICONS宏
在对话框接收到WM_INITDIALOG消息的时候调用chSETDLGICONS来设置图标
//////////////////////// Dialog Box Icon Setting Macro ////////////////////////// Sets the dialog box iconsinline void chSETDLGICONS(HWND hWnd, int idi) { SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi))); SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));}
强制编译器寻找wWinMain入口函数
Solution设置控制台默认入口函数是 (w)main
而GUI程序默认入口函数是 _tWinMain
cmmhdr.h中使用了一条pragma强制寻找WinMain入口函数
通过pragma预处理指令来支持XP风格的用户界面主题
Microsoft提供了一个manifestdependency选项默认支持xp+ style的风格
- 《Windows核心编程》读书笔记零 构建环境
- Windows核心编程读书笔记
- Windows 核心编程读书笔记
- Windows核心编程读书笔记
- Windows 核心编程 -- 读书笔记
- windows核心编程读书笔记
- 《Windows核心编程》读书笔记
- 《Windows核心编程》读书笔记
- 【读书笔记】Windows核心编程
- 【读书笔记】windows核心编程
- 《Windows核心编程》读书笔记(四)
- 《Windows核心编程》读书笔记 (五)
- Windows核心编程读书笔记I
- 《Windows核心编程》第一章 读书笔记
- windows核心编程读书笔记一
- [C++]《Windows核心编程》读书笔记
- [C++]《Windows核心编程》读书笔记
- Windows核心编程读书笔记6-多线程编程
- Android开发之~java.lang.ClassNotFoundException: Didn't find class "android.view.x" on path: ...
- dijkstra算法代码实现
- Java —— static 关键字、static 内部类、枚举类
- spring系列(三)——springAOP原理探究(CGLIB代理机制)
- 锁
- 《Windows核心编程》读书笔记零 构建环境
- Elasticsearch集群Linux搭建
- 预处理入库的方式
- python zip和tar两种格式的压缩与解压
- Parse 和 TryParse
- select a method for export 各项的意思
- Android颜色选择器
- 办公不用愁,在线pdf转换器帮你提升工作效率
- 第1章-如何使用本书—零死角玩转STM32-F429系列