Win32 动态库dll
这两天学习动态库的练习,分享下方法
实例.封装窗口类的两种状态.
1.自定义窗口类QWnd
2.资源模板窗口对话框类
下面是dll的头文件,类的声明
#pragma once
#ifndef _CLASSDLL_H_
#define _CLASSDLL_H_ #include <windows.h>
#include <assert.h> //定义导入与导出类的宏标识
//在动态库的.cpp文件中定义DLLCLASS_EXPORTS表示导出类函数
#ifdef DLLCLASS_EXPORTS
#define EXT_CLASS _declspec(dllexport) //定义导出类
#else
#define EXT_CLASS _declspec(dllimport) //定义导入类
#endif /*
* QWnd Class
*/
class EXT_CLASS QWnd { public:
QWnd();
public://成员函数 //创建窗口
//参数说明:
// 1.lpClassName: .窗口类名
// 2.lpWndName:....窗口标题
// 3.dwStyle: .....窗口风格样式
// 4.x,y,nWidth,nHegiht: ...窗口位置和宽高
// 5.hParent: .....父窗口句柄
// 6.meunID: ......菜单句柄(子窗口为子窗口ID)
BOOL CreateWindowX(LPCTSTR lpClassName,
LPCTSTR lpWndName, UINT dwStyle,
int x, int y, int nWidth, int nHegiht,
HWND hParent, HMENU menuID,
HINSTANCE hInstance);
/******
静态消息回调函数
*/
static LRESULT CALLBACK lpWindowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam); //实际的消息回调处理函数
virtual LRESULT MyWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam); //显示窗口
BOOL ShowWindow(int nCmdShow);
//更新窗口
BOOL UpdateWindow()const;
//消息循环
BOOL RunMsg()const; public: //成员变量
HWND m_hWnd; //窗口句柄
HINSTANCE m_hInstance; //程序实例句柄
LPVOID m_lpVoid; //窗口附加数据,用于窗口间传递数据 public: //msg消息处理函数
virtual LRESULT OnDestroy(WPARAM wParam, LPARAM lParam); //窗口销毁消息
virtual LRESULT OnCreate(WPARAM wParam, LPARAM lParam); //窗口创建消息
virtual LRESULT OnClose(WPARAM wParam, LPARAM lParam); //窗口关闭消息
virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam); //响应按键消息
virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam); //子窗口通知消息
virtual LRESULT OnPaint(WPARAM wParam, LPARAM lParam); //窗口重绘消息
virtual LRESULT OnLButtonDBlclk(WPARAM wParam, LPARAM lParam); //鼠标左键双击消息
virtual LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); //鼠标左键按下消息
virtual LRESULT OnLButtonUp(WPARAM wParam, LPARAM lParam); //鼠标左键弹起消息
virtual LRESULT OnRButtonDBlclk(WPARAM wParam, LPARAM lParam); //鼠标右键双击消息
virtual LRESULT OnRButtonDown(WPARAM wParam, LPARAM lParam); //鼠标右键按下消息
virtual LRESULT OnRButtonUp(WPARAM wParam, LPARAM lParam); //鼠标右键弹起消息
virtual LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam); //鼠标移动消息
virtual LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam); //
virtual LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam); //鼠标滚轮消息
virtual LRESULT OnMouseLast(WPARAM wParam, LPARAM lParam); //
virtual LRESULT OnSysCommand(WPARAM wParam, LPARAM lParam); //系统按钮消息
}; /*
* QDialogEx Class
*/
class EXT_CLASS QDialogEx:public QWnd
{
public:
QDialogEx(QWnd* pPrent = NULL, DWORD dlgIDD = 0);
static INT_PTR CALLBACK lpDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual INT_PTR MyDlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
//创建模板资源对话框
// 参数说明:
// 1.hInstance: ..程序实例句柄
// 2.dlgIDD: .....对话框资源ID号
// 3.hParent: ....父窗口句柄
BOOL CreateDialogX(HINSTANCE hInstance, UINT dlgIDD, HWND hParent = NULL);
//模态对话框(父窗口类的对象)
INT_PTR DoModul(QWnd* pParent); public://msg
virtual INT_PTR OnInitDialog(WPARAM wParam, LPARAM lParam); //初始化对话框消息
virtual LRESULT OnClose(WPARAM wParam, LPARAM lParam); //关闭消息
virtual LRESULT OnDestroy(WPARAM wParam, LPARAM lParam); //销毁窗口消息
virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam); public:
BOOL m_IsModul; //是否是模态窗口
UINT m_IDD; //对话框的资源ID
LPARAM m_lParam;//窗口附加数据,用于数据的传进与传出
}; #endif
弄了好久才弄好,途中错误连连,不过也学到不少东西.
下面是dll.cpp文件
#define DLLCLASS_EXPORTS
#include "Classdll.h" #pragma region 窗口类QWnd QWnd::QWnd()
{
m_hInstance = 0;
m_hWnd = 0;
m_lpVoid = 0;
} BOOL QWnd::CreateWindowX(LPCTSTR lpClassName, LPCTSTR lpWndName,
UINT dwStyle, int x, int y, int nWidth, int nHegiht,
HWND hParent, HMENU menuID,
HINSTANCE hInstance)
{
m_hInstance = hInstance;
//设计自定义窗口类
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(WNDCLASSEX);
if (!GetClassInfoEx(hInstance, lpClassName, &wcx))
{
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.lpfnWndProc = lpWindowProc;
wcx.lpszClassName = lpClassName;
wcx.lpszMenuName = NULL;
wcx.hbrBackground = (HBRUSH)(COLOR_3DFACE);
wcx.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wcx.hIcon = ::LoadIcon(NULL, IDI_WINLOGO);
wcx.hIconSm = ::LoadIcon(NULL, IDI_WINLOGO);
wcx.hInstance = hInstance;
wcx.style = CS_VREDRAW | CS_HREDRAW; //注册窗口类
if (!RegisterClassEx(&wcx))
{
OutputDebugString(TEXT("窗口类注册失败!!!"));
return FALSE;
}
} //创建窗口
m_hWnd = ::CreateWindowEx(0, lpClassName, lpWndName,
dwStyle,x,y,nWidth,nHegiht,
hParent, menuID, hInstance,this);
if (NULL == m_hWnd)
{
OutputDebugString(TEXT("窗口创建失败!!!!"));
return FALSE;
}
return TRUE;
} LRESULT CALLBACK QWnd::lpWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (WM_CREATE == uMsg)
{
QWnd* pWnd = (QWnd*)((CREATESTRUCT*)lParam)->lpCreateParams;
if (pWnd)
{
pWnd->m_hWnd = hWnd;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)pWnd);
return pWnd->MyWndProc(uMsg, wParam, lParam);
}
} QWnd* pWnd = (QWnd*)GetWindowLongPtr(hWnd, GWL_USERDATA);
if (pWnd)
{
return pWnd->MyWndProc(uMsg, wParam, lParam);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam); } LRESULT QWnd::MyWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
return OnDestroy(wParam, lParam);
case WM_CREATE: return OnCreate(wParam, lParam);
case WM_CLOSE: return OnClose(wParam, lParam);
case WM_COMMAND: return OnCommand(wParam, lParam);
case WM_SYSCOMMAND:
OnSysCommand(wParam, lParam);
break;
case WM_NOTIFY: return OnNotify(wParam, lParam);
case WM_PAINT:
OnPaint(wParam, lParam);
break; case WM_LBUTTONDBLCLK: return OnLButtonDBlclk(wParam, lParam);
case WM_LBUTTONDOWN: return OnLButtonDown(wParam, lParam);
case WM_LBUTTONUP: return OnLButtonUp(wParam, lParam);
case WM_RBUTTONDBLCLK: return OnRButtonDBlclk(wParam, lParam);
case WM_RBUTTONDOWN: return OnRButtonDown(wParam, lParam);
case WM_RBUTTONUP: return OnRButtonUp(wParam, lParam);
case WM_MOUSEMOVE: return OnMouseMove(wParam, lParam);
case WM_MOUSELEAVE: return OnMouseLeave(wParam, lParam);
case WM_MOUSEWHEEL: return OnMouseWheel(wParam, lParam);
case WM_MOUSELAST: return OnMouseLast(wParam, lParam); } return DefWindowProc(m_hWnd, uMsg, wParam, lParam);
} BOOL QWnd::ShowWindow(int nCmdShow)
{
assert(m_hWnd);
return ::ShowWindow(m_hWnd, nCmdShow);
} BOOL QWnd::UpdateWindow() const
{
assert(m_hWnd);
return ::UpdateWindow(m_hWnd);
} BOOL QWnd::RunMsg() const
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
} #pragma region 虚函数
LRESULT QWnd::OnDestroy(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnCreate(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnClose(WPARAM wParam, LPARAM lParam)
{ return 0;
} LRESULT QWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnNotify(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnPaint(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnLButtonDBlclk(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnRButtonDBlclk(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnRButtonDown(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnRButtonUp(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnMouseLast(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QWnd::OnSysCommand(WPARAM wParam, LPARAM lParam)
{
return 0;
} #pragma endregion #pragma endregion 窗口类 #pragma region 对话框类QDialogEx QDialogEx::QDialogEx(QWnd * pPrent, DWORD dlgIDD)
{
m_IsModul = FALSE;
m_IDD = (dlgIDD != 0) ? dlgIDD : 0;
} INT_PTR CALLBACK QDialogEx::lpDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (WM_INITDIALOG == uMsg)
{
QDialogEx* pDlg = (QDialogEx*)lParam;
if (pDlg)
{
pDlg->m_hWnd = hWnd;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)pDlg);
return pDlg->MyDlgProc(uMsg, wParam, lParam); }
} QDialogEx* pDlg = (QDialogEx*)GetWindowLongPtr(hWnd, GWL_USERDATA);
if (pDlg)
{
return pDlg->MyDlgProc(uMsg, wParam, lParam);
} return 0;
} INT_PTR QDialogEx::MyDlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG: return OnInitDialog(wParam, lParam);
case WM_COMMAND: return OnCommand(wParam, lParam);
case WM_NOTIFY: return OnNotify(wParam, lParam);
case WM_CLOSE: return OnClose(wParam, lParam);
case WM_DESTROY: return OnDestroy(wParam, lParam); }
return INT_PTR();
} BOOL QDialogEx::CreateDialogX(HINSTANCE hInstance, UINT dlgIDD, HWND hParent /*= NULL*/)
{
m_hInstance = hInstance;
m_hWnd = ::CreateDialogParam(hInstance, MAKEINTRESOURCE(dlgIDD), hParent,lpDialogProc, (LPARAM)this);
if (NULL == m_hWnd)
{
OutputDebugString(TEXT("创建对话框资源窗口失败!!!"));
return FALSE;
}
return TRUE;
} INT_PTR QDialogEx::DoModul(QWnd* pParent)
{
assert(pParent);
m_IsModul = TRUE;
return ::DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(m_IDD), pParent->m_hWnd,lpDialogProc,(LPARAM)this);
} INT_PTR QDialogEx::OnInitDialog(WPARAM wParam, LPARAM lParam)
{
return 0;
} LRESULT QDialogEx::OnClose(WPARAM wParam, LPARAM lParam)
{ return 0;
} LRESULT QDialogEx::OnDestroy(WPARAM wParam, LPARAM lParam)
{ return 0;
} LRESULT QDialogEx::OnCommand(WPARAM wParam, LPARAM lParam)
{
return 0;
} #pragma endregion 对话框类QDialogEx
本想弄到一个消息处理函数中,但是冲途好多,就弄了两个处理消息函数,以后弄明白再说吧.现在能用就OK
用法:
1.将生成的.dll .lib .h三个文件拷到要用的工程目录下,
2.在工程中声明
#include "../Classdll/Classdll.h" //这是声明动态库的头文件,你放在什么地方就写什么地方
#pragma comment(lib,"../Debug/Classdll.lib") //这是引入动态库.dll,和上面一样,放在什么地方就写什么地方
测试:
int main()
{
#if 0 //定位内存漏泄所在代码位置
_CrtSetBreakAlloc(13);
#endif HINSTANCE hInstance=GetModuleHandle(NULL);
MyDialog dlg;
dlg.CreateDialogX(hInstance, IDD_DIALOG1, NULL);
dlg.ShowWindow(SW_SHOW);
dlg.UpdateWindow();
dlg.RunMsg(); #ifdef _DEBUG
_CrtDumpMemoryLeaks(); //检查内存漏泄
#endif return 0;
}
效果:

因是在控制台测试的,所以有控制台的黑窗口
Win32 动态库dll的更多相关文章
- 五,动态库(dll)的封装与使用
在项目开发中,我们经常会使用到动态库(dll),要么是使用别人的动态库,要么是将功能函数封装为动态库给别人用.那么如何封装和使用动态库呢?以下内容为你讲解. 1.动态库的封装 以vs2010为例,我们 ...
- 在VS2015中用C++编写可被其它语言调用的动态库DLL
转自:http://blog.csdn.net/songyi160/article/details/50754705 VS2015用C++创建动态库DLL步骤如下: (1)启动VS2015>文件 ...
- 编译Win32动态库工程的两个链接错误的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 今天编译一个Win32动态库工程,出现两个链接错误的解决,一个是: main.obj: error LNK2001: ...
- Qt编写自定义控件插件开放动态库dll使用(永久免费)
这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本 ...
- C++与C#有关对库(动态库dll,静态库.lib)文件的调用
1 动态库的相互调用 1.1 C#调用C++ dll步骤(只能导出方法): 1. c++建立空项目->源文件文件夹中添加cpp文件和函数 2. c++属性设置中,配置类型设置为动态库dll,公共 ...
- Qt生成和调用动态库dll,和静态库.a(windows和linux通用)
系统1:ThinkPad T570.Windows10.QT5.12.2(Qt Creater 4.8.2)一.动态库.dll的创建和调用1.在qtcreater中按如下步骤创建动态库,动态库名为my ...
- 动态库DLL加载方式-静态加载和动态加载
静态加载: 如果你有a.dll和a.lib,两个文件都有的话可以用静态加载的方式: message函数的声明你应该知道吧,把它的声明和下面的语句写到一个头文件中 #pragma comment(lib ...
- qt使用动态库(DLL)
本文主要讲解在QT开发环境中如何使用VC生成的DLL及QT自身生成的DLL.至于其它情况本文不作讨论. 连接库分为2种 (1)动态连接库,通常有.h .lib .dll三个文件,功能实现在dll中 ( ...
- Qt中添加静态库.lb,.a和动态库.dll,.so,头文件和.cpp文件
添加步骤 1.-Qt Creator中,"项目"------"添加库"2.把静态库和动态库文件放到项目文件夹中3.在.pro文件中会添加如下代码: - 添加动态 ...
- C/C++ 关于生成静态库(lib)/动态库(dll)文件如何使用(基于windows基础篇)
1. 首先,如何制作一个静态库(lib)? 额, 对于静态库,我们知道,里头是不应该有Main函数,它只是一个配合文件.之所以称之为lib静态库,其实就是指,我们需要用到lib里头的函数时,我们才会去 ...
随机推荐
- 慕课DJANGO配置
重写内置的错误处理视图 在项目urls.py中添加配置 handler500 = "app01.views.page_500" handler404 = "app01.v ...
- P3731 题解
简要题意是找到一条边连接使得最大团大小增加. 在补图上最大团等于最大独立集. 所以问题转化为删掉一条边使得最大独立集增加,又因为团不超过两个,所以原图是二分图,也就是使得最大匹配减少. 考虑什么样的匹 ...
- C#委托的2种调用方式
第一种:直接调用,通过invoke方法: 第二种:这是第二种将委托作为方法的参数的间接调用: 下面举个栗子演示: using System; using System.Collections.Gene ...
- [oeasy]python0048_注释_comment_设置默认编码格式
注释Comment 回忆上次内容 使用了版本控制 git 制作备份 进行回滚 尝试了 嵌套的控制结构 层层 控制 不过 除非 到不得以 尽量不要 太多层次的嵌套 这样 从顶到底 含义 明确 ...
- [oeasy]python0109_tty_打字头_电传打字机_字模_点阵字库
点阵字库 回忆上次内容 上次回顾了 字符字型 的 进化过程 从 谷腾堡 活字 到 罗马正字 和 意大利斜体 罗马帝国战斗力的征服 和 基督教文化传播 使得 拉丁字符 在日耳曼语地区广泛传播 种葡萄 ...
- oeasy教您玩转vim - 66 - # 比较修改模式 vimdiff
vimdiff 回忆上次 上次有三种批量替换,分别是 :windo :bufdo :argdo 执行的{cmd}可以用|按顺序增加 update 自动更新 :set autowrite 自动写入 ...
- 简单的字符串处理函数_C语言
字符串数组 // Code file created by C Code Develop #include "stdio.h" #include "stdlib.h&qu ...
- Jmeter函数助手12-threadNum
threadNum函数用于获取当前线程编号.该函数没有参数,直接引用即可. 1.线程数可在组件[测试计划->线程组]设置.如下是不传入循环次数的${__threadNum}. "调试取 ...
- Python异常处理try+except用法
1.except是用来捕获程序异常的 异常代码如: ModuleNotFoundError(没有找到模块,安装提示的模块即可) AttributeError(没有访问属性) TypeError(类型错 ...
- 4、SpringBoot2之整合SpringMVC
创建名为springboot_springmvc的新module,过程参考3.1节 4.1.重要的配置参数 在 spring boot 中,提供了许多和 web 相关的配置参数(详见官方文档),其中有 ...