这两天学习动态库的练习,分享下方法

实例.封装窗口类的两种状态.

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的更多相关文章

  1. 五,动态库(dll)的封装与使用

    在项目开发中,我们经常会使用到动态库(dll),要么是使用别人的动态库,要么是将功能函数封装为动态库给别人用.那么如何封装和使用动态库呢?以下内容为你讲解. 1.动态库的封装 以vs2010为例,我们 ...

  2. 在VS2015中用C++编写可被其它语言调用的动态库DLL

    转自:http://blog.csdn.net/songyi160/article/details/50754705 VS2015用C++创建动态库DLL步骤如下: (1)启动VS2015>文件 ...

  3. 编译Win32动态库工程的两个链接错误的解决

    作者:朱金灿 来源:http://blog.csdn.net/clever101 今天编译一个Win32动态库工程,出现两个链接错误的解决,一个是: main.obj: error LNK2001: ...

  4. Qt编写自定义控件插件开放动态库dll使用(永久免费)

    这套控件陆陆续续完善了四年多,目前共133个控件,除了十几个控件参考网友开源的代码写的,其余全部原创,在发布之初就有打算将动态库开放出来永久免费使用,在控件比较完善的今天抽了半天时间编译了多个qt版本 ...

  5. C++与C#有关对库(动态库dll,静态库.lib)文件的调用

    1 动态库的相互调用 1.1 C#调用C++ dll步骤(只能导出方法): 1. c++建立空项目->源文件文件夹中添加cpp文件和函数 2. c++属性设置中,配置类型设置为动态库dll,公共 ...

  6. Qt生成和调用动态库dll,和静态库.a(windows和linux通用)

    系统1:ThinkPad T570.Windows10.QT5.12.2(Qt Creater 4.8.2)一.动态库.dll的创建和调用1.在qtcreater中按如下步骤创建动态库,动态库名为my ...

  7. 动态库DLL加载方式-静态加载和动态加载

    静态加载: 如果你有a.dll和a.lib,两个文件都有的话可以用静态加载的方式: message函数的声明你应该知道吧,把它的声明和下面的语句写到一个头文件中 #pragma comment(lib ...

  8. qt使用动态库(DLL)

    本文主要讲解在QT开发环境中如何使用VC生成的DLL及QT自身生成的DLL.至于其它情况本文不作讨论. 连接库分为2种 (1)动态连接库,通常有.h .lib .dll三个文件,功能实现在dll中 ( ...

  9. Qt中添加静态库.lb,.a和动态库.dll,.so,头文件和.cpp文件

    添加步骤 1.-Qt Creator中,"项目"------"添加库"2.把静态库和动态库文件放到项目文件夹中3.在.pro文件中会添加如下代码: - 添加动态 ...

  10. C/C++ 关于生成静态库(lib)/动态库(dll)文件如何使用(基于windows基础篇)

    1. 首先,如何制作一个静态库(lib)? 额, 对于静态库,我们知道,里头是不应该有Main函数,它只是一个配合文件.之所以称之为lib静态库,其实就是指,我们需要用到lib里头的函数时,我们才会去 ...

随机推荐

  1. C#使用RegNotifyChangeKeyValue监听注册表更改的几种方式

    养成一个好习惯,调用 Windows API 之前一定要先看文档 RegNotifyChangeKeyValue 函数 (winreg.h) - Win32 apps | Microsoft Lear ...

  2. 浮点数格式:FP64, FP32, FP16, BFLOAT16, TF32之间的相互区别

    浮点数格式 (参考1,参考2) 浮点数是一种用二进制表示的实数,它由三个部分组成:sign(符号位).exponent(指数位)和fraction(小数位).不同的浮点数格式有不同的位数分配给这三个部 ...

  3. LangGraph实战

    1.概述 前段时间LangChain发布了LangGraph,它引起了很多关注.LangGraph 的主要优势在于它能够实现循环工作流,这对于在 LLM 应用程序中模拟类似代理的行为至关重要.本篇博客 ...

  4. 【简单总结】SLAM 算法的 Benchmark 及相关数据集的结果对比

    前言与参考 主要是copy一下总结,方便自己后续找方案特定使用,所有的出处均在标题处和原链接跳转,此处仅做各个benchmark收集使用,如果有原作者觉得侵权,请联系我 将全力配合相关内容和链接删除 ...

  5. 全志科技T507-H工业核心板规格书(4核ARM Cortex-A53,主频1.416GHz)

    1 核心板简介 创龙科技SOM-TLT507是一款基于全志科技T507-H处理器设计的4核ARM Cortex-A53全国产工业核心板,主频高达1.416GHz.核心板CPU.ROM.RAM.电源.晶 ...

  6. 在VisualStudio中WPF应用程序在打开窗体界面设计时报错<发生了未经处理的异常>的解决方法

    在网上找了一个wpf的开源项目,在打开窗体,点击设计的时候,提示错误信息如下 System.Resources.MissingSatelliteAssemblyExceptionThe satelli ...

  7. MongoDB安装、基础操作和聚合实例详解

    虽然MongoDB这些年很流行,但笔者之前没研究过,现在有需求研究这类NoSQL的数据库,是为了验证其是否可被替换. MongoDB是很轻量的文档数据库,简单测试也懒得专门准备虚拟机环境了,直接在ma ...

  8. 解决方案 | cad选择集找出包含特定字符串的多行文本

    代码如下: 1 # 选择文本中出现特定单词的多行文字 2 # 下面的代码将选择条件定义为文本字符串中出现"The"的任意选项.此示例还演示了选择方法的用法:MtextSelectB ...

  9. 判断C盘下有没有Templets文件夹,没有则新建,然后判断Templets文件夹下有没有TEST.xlt文件

    VB.NET 判断C盘下有没有Templets文件夹,没有则新建,然后判断Templets文件夹下有没有TEST.xlt文件,如果没有则新建   你可以使用VB.NET中的Directory和File ...

  10. 构建基于Java Spring Boot和Uniapp的心理小程序:从零到一的完整指南

    构建基于Java Spring Boot和Uniapp的心理小程序:从零到一的完整指南 前言 大家好,今天我们来聊聊如何使用Java Spring Boot和Uniapp构建一个心理小程序.这个项目不 ...