二、库(静态库&动态库)
1.静态库
静态库是指我们的应用中,有一些公共代码是需要反复使用的,就把这些代码编译为库,理解为仓库,在仓库中存储了很多的东西,每次使用就只需要去仓库拿就可以了。
创建静态库
在创建项目时就选择创建静态库,然后再静态库中创建头文件,以及实现头文件函数的cpp文件,然后就可以了。最后将静态库的文件复制到新的项目中就可以使用了。
2.动态库
动态库又称动态链接库,英文“dll”,是“Dynamic Link Library”的缩写。
DLL是一个包含可有多个程序同时使用的代码和数据的库;
DLL不是可执行文件。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
函数的可执行代码位于一个DLL中,该DLL包含一个或多个已被编译,连接并使用他们的进程的函数。
windows下一般文件后缀为“.dll”,Linux下为“.so”后缀。
创建动态库和静态库相似。
静态库和动态库的区别
1.静态库在程序的连接阶段被复制到了程序中,和程序运行的时候没有关系。
2.动态库再链接阶段没有被复制到程序中,而是在程序运行中由系统加载到内存中供使用。
优点
使用静态库的优点
1.代码装载速度快,执行速度比链接速度略快。
2.发布程序时不需要考录到计算机上是否还存在“.ib文件"
使用动态库的优点
1.更加节省内存,减少页面交换。
2.dll文件和exe文件独立,只要输出接口不变(即名称,参数,返回值类型不变),DLL文件不会对exe文件造成任何影响,因而极大的提高了程序的可维护性,和课拓展性;
3.不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL文件。
4.适用于大规模的软件开发,使开发过程独立,耦合度小,便于不同的开发者和组织之间进行开发和测试。
代码呈现
// WindowsProject2.cpp : 定义应用程序的入口点。 // /* 1.入口函数; 2.窗口注册函数 3.窗口创建函数 4.显示窗口 5.更新窗口 6.主消息循环 7.入口函数返回; */ #include "framework.h" #include "WindowsProject2.h" #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, //入口函数; _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此处放置代码。 // 初始化全局字符串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT2, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT2)); // MSG msg; /* //窗口示例,如果需要就可以去掉; if (MessageBox(0, _T("你是否要选择轰炸"), _T("提示"), MB_ABORTRETRYIGNORE) == IDABORT) { MessageBoxW(0, _T("对你要轰炸的对象操作"), _T("选择按钮"), 0); }*/ //自己添加的消息提示 // 主消息循环: //while (GetMessage(&msg, nullptr, 0, 0)) //当获得的消息为真时,就返回true; //{ // if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) //判断是不是快捷键; // { // TranslateMessage(&msg); // DispatchMessage(&msg); // } //} MSG msg; //使用peekMessage() ZeroMemory(&msg, sizeof(msg)); //初始化; /* VOID ZeroMemory( PVOID 【目的地】, //填写零的块地址 DWORD 【长度】 //以块的大小(以字节为单位)填充零 ); */ while (msg.message != WM_QUIT) //如果不是退出的消息,就执行消息循环; { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) //只要鼠标移动,就执行; PM_NOEMOVE是不移动; { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) //判断是不是快捷键; { TranslateMessage(&msg); DispatchMessage(&msg); } } } return (int) msg.wParam; } // // 函数: MyRegisterClass() // // 目标: 注册窗口类。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; //表示一个窗口类型的结构体变量; wcex.cbSize = sizeof(WNDCLASSEX); //表示的是自身这个类型的大小; wcex.style = CS_HREDRAW | CS_VREDRAW; //风格; wcex.lpfnWndProc = WndProc; //**非常重要(窗口消息处理函数) wcex.cbClsExtra = 0; //类的额外信息; wcex.cbWndExtra = 0; //窗口的额外信息; wcex.hInstance = hInstance; //当前实例句柄; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT2)); //图标,菜单栏图标; wcex.hCursor = LoadCursor(0, nullptr); //光标; wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景,一般不需要改变; wcex.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1); // 菜单; wcex.lpszClassName = szWindowClass; // 窗口类名; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); //图标,窗口左上角的图标; return RegisterClassExW(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目标: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // //创建窗口函数; BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 将实例句柄存储在全局变量中 //HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); //从资源中加载窗口; // 动态加载 //1.创建一个新菜单 HMENU hmenu = nullptr; hmenu = CreateMenu(); //2.向菜单中添加选项; AppendMenu(hmenu,/*在哪一个菜单中添加;*/ MF_POPUP, 1086, _T("新建(&N)")); AppendMenu(hmenu,/*在哪一个菜单中添加;*/ MF_POPUP, 1087, _T("打开(&O)")); HMENU hmenu3 = CreateMenu(); AppendMenu(hmenu3, MF_POPUP, 1088, _T("转到(&G)")); AppendMenu(hmenu3, MF_POPUP, 1089, _T("替换(&F)")); HMENU hmenu2 = CreateMenu(); AppendMenu(hmenu2, MF_POPUP, (UINT)hmenu, _T("文件(&F)")); AppendMenu(hmenu2, MF_POPUP, (UINT)hmenu3, _T("编辑(&E)")); HWND hWnd = CreateWindowW(szWindowClass, //窗口类名,注意,必须是已经注册的窗口类名; szTitle, //窗口标题名; WS_OVERLAPPEDWINDOW| WS_VSCROLL, // 窗口风格; CW_USEDEFAULT, //窗口的坐标x 0, // 窗口的y坐标 CW_USEDEFAULT, //窗口的宽度 0, //窗口的高度 nullptr, //父窗口菜单句柄 hmenu2, // 窗口菜单句柄,这里可以加载窗口; hInstance, //当前实例句柄 nullptr); // 保留参数; if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目标: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // HMENU g_Menu; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { g_Menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU2)); } break; case WM_RBUTTONDOWN: { POINT pt; /*pt.x = LOWORD(lParam); pt.y = LOWORD(lParam); ClientToScreen(hWnd, &pt);*/ GetCursorPos(&pt); HMENU tempmenu = GetSubMenu(g_Menu, 0); TrackPopupMenu(tempmenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, nullptr); } break; case WM_CHAR: //字符消息; { switch (wParam) { case VK_RETURN: MessageBoxA(hWnd, "回车键", "提示", 0); break; case 'Z': { HDC hdc = GetDC(hWnd); TextOutA(hdc, 30, 30, "快捷键Alt+X",8 ); ReleaseDC(hWnd, hdc); } break; } } //case WM_ACTIVATE: //窗口激活; //{ // switch (wParam) // { // case WA_CLICKACTIVE: //鼠标点击激活; // { // HDC hdc = GetDC(hWnd); // static int j = 0; // TextOutA(hdc, 0, j, "加油,未来可期", 7); // j += 20; // } // break; //case WA_ACTIVE: //通过鼠标以外的方式激活; //{ // HDC hdc = GetDC(hWnd); // static int j = 0; // TextOutA(hdc, 30, j, "加油,未来可期", 7); // j += 20; //} // break; //case WA_INACTIVE: //停用; //{ // MessageBoxA(hWnd, "停用", "提示", 0); //} //break; /* } }*/ //case WM_CREATE: //窗口创建; // MessageBoxA(hWnd,"你是否要打开窗口"," 提示",0); //利用弹窗来显示窗口创建成功; // break; case WM_COMMAND: //菜单命令; { int wmId = LOWORD(wParam); // 分析菜单选择: switch (wmId) { break; case 1086: MessageBox(hWnd, _T("快捷键Ctrl+N,新建文件"), _T("提示"), 0); break; case 1087: MessageBox(hWnd, _T("快捷键Ctrl+O,打开文件"), _T("提示"), 0); break; case 1088: MessageBox(hWnd, _T("快捷键Ctrl+E,转到文件"), _T("提示"), 0); break; case 1089: MessageBox(hWnd, _T("快捷键Ctrl+F,查找文件"), _T("提示"), 0); break; case ID_32774: { int i = 0; HWND hwnd = FindWindowA(0, "我的Android手机"); //查找窗口; for (i = 0; i < 10; i++) { PostMessage(hwnd, WM_PASTE, 0, 0); PostMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0); } MessageBox(hwnd,_T("消息轰炸开始"),_T("提示"),0); } case IDB_BITMAP1: MessageBox(0, 0, 0, 0); break; case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); //消息默认处理函数; } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此处添加使用 hdc 的任何绘图代码... EndPaint(hWnd, &ps); } break; case WM_DESTROY: //MessageBoxA(hWnd, "你将会关闭窗口", "警告", MB_OKCANCEL); //弹窗显示; PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “关于”框的消息处理程序。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
总结
`win32的内容就更到这里了,下面就是mfc内容了,win32需要记的东西很多,需要花大量时间去熟悉,多去尝试就能够掌握。