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;
}

效果:

 因是在控制台测试的,所以有控制台的黑窗口

签名:GreenLeaf1976
原文地址:https://www.cnblogs.com/greenleaf1976/p/14758456.html