From 581d2d139e2e6a8cc9923c88b33f70f32c9da10b Mon Sep 17 00:00:00 2001 From: luoliangyi <87842688@qq.com> Date: Thu, 21 Jul 2022 16:20:51 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4twain=5Fuser=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/windows/HGTest/HGTestDlg.cpp | 29 +++---- modules/twain_user/HGTwain.cpp | 14 ++- modules/twain_user/HGTwain.h | 8 +- modules/twain_user/HGTwainImpl.cpp | 135 +++++++++++++---------------- modules/twain_user/HGTwainImpl.hpp | 18 ++-- modules/twain_user/dllmain.cpp | 4 - 6 files changed, 90 insertions(+), 118 deletions(-) diff --git a/build/windows/HGTest/HGTestDlg.cpp b/build/windows/HGTest/HGTestDlg.cpp index d35c44a6..61cc378c 100644 --- a/build/windows/HGTest/HGTestDlg.cpp +++ b/build/windows/HGTest/HGTestDlg.cpp @@ -104,6 +104,9 @@ BOOL CHGTestDlg::OnInitDialog() SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 + HGTwain_LoadDSM(&m_dsm); + HGTwain_OpenDSM(m_dsm, m_hWnd, DSEventCallback, this); + return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } @@ -158,30 +161,24 @@ HCURSOR CHGTestDlg::OnQueryDragIcon() void CHGTestDlg::OnBnClickedButton1() { - if (NULL != m_dsm) + if (NULL != m_ds) { return; } - HGTwain_LoadDSM(&m_dsm); - HGTwain_OpenDSM(m_dsm); HGTwain_SelectDS(m_dsm, &m_ds); - if (NULL == m_ds) + if (NULL != m_ds) { - HGTwain_UnloadDSM(m_dsm); - m_dsm = NULL; - return; + HGTwain_OpenDS(m_ds); + HGTwain_EnableDS(m_ds, HGTRUE, NULL); } - - HGTwain_OpenDS(m_ds); - HGTwain_EnableDS(m_ds, HGFALSE, NULL, DSEventCallback, this); } void CHGTestDlg::OnBnClickedButton2() { - HGTwain_UnloadDSM(m_dsm); - m_dsm = NULL; + HGTwain_CloseDS(m_ds); + m_ds = NULL; } void CHGTestDlg::DSEventCallback(HGTwainDS ds, HGUInt event, HGPointer param) @@ -218,12 +215,12 @@ void CHGTestDlg::DSEventCallback(HGTwainDS ds, HGUInt event, HGPointer param) } else if (HGTWAIN_DSEVENT_CLOSEDSREQ == event) { - HGTwain_UnloadDSM(p->m_dsm); - p->m_dsm = NULL; + HGTwain_CloseDS(p->m_ds); + p->m_ds = NULL; } else if (HGTWAIN_DSEVENT_CLOSEDSOK == event) { - HGTwain_UnloadDSM(p->m_dsm); - p->m_dsm = NULL; + HGTwain_CloseDS(p->m_ds); + p->m_ds = NULL; } } diff --git a/modules/twain_user/HGTwain.cpp b/modules/twain_user/HGTwain.cpp index d810b27a..94e3be9e 100644 --- a/modules/twain_user/HGTwain.cpp +++ b/modules/twain_user/HGTwain.cpp @@ -38,7 +38,7 @@ HGResult HGAPI HGTwain_UnloadDSM(HGTwainDSM dsm) return HGBASE_ERR_OK; } -HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm) +HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm, HWND hwnd, HGDSEventFunc func, HGPointer param) { if (NULL == dsm) { @@ -46,7 +46,7 @@ HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm) } HGTwainDSMImpl* twainDSMImpl = (HGTwainDSMImpl*)dsm; - return twainDSMImpl->OpenDSM(); + return twainDSMImpl->OpenDSM(hwnd, func, param); } HGResult HGAPI HGTwain_CloseDSM(HGTwainDSM dsm) @@ -148,8 +148,7 @@ HGResult HGAPI HGTwain_GetCapability(HGTwainDS ds, HGUInt cap, HGInt* value) return twainDSImpl->dsmImpl->GetCapability(twainDSImpl, cap, value); } -HGResult HGAPI HGTwain_EnableDSUIOnly(HGTwainDS ds, HGBool showUI, HWND parent, - HGDSEventFunc func, HGPointer param) +HGResult HGAPI HGTwain_EnableDSUIOnly(HGTwainDS ds, HGBool showUI, HWND parent) { if (NULL == ds) { @@ -157,11 +156,10 @@ HGResult HGAPI HGTwain_EnableDSUIOnly(HGTwainDS ds, HGBool showUI, HWND parent, } HGTwainDSImpl* twainDSImpl = (HGTwainDSImpl*)ds; - return twainDSImpl->dsmImpl->EnableDSUIOnly(twainDSImpl, showUI, parent, func, param); + return twainDSImpl->dsmImpl->EnableDSUIOnly(twainDSImpl, showUI, parent); } -HGResult HGAPI HGTwain_EnableDS(HGTwainDS ds, HGBool showUI, HWND parent, - HGDSEventFunc func, HGPointer param) +HGResult HGAPI HGTwain_EnableDS(HGTwainDS ds, HGBool showUI, HWND parent) { if (NULL == ds) { @@ -169,7 +167,7 @@ HGResult HGAPI HGTwain_EnableDS(HGTwainDS ds, HGBool showUI, HWND parent, } HGTwainDSImpl* twainDSImpl = (HGTwainDSImpl*)ds; - return twainDSImpl->dsmImpl->EnableDS(twainDSImpl, showUI, parent, func, param); + return twainDSImpl->dsmImpl->EnableDS(twainDSImpl, showUI, parent); } HGResult HGAPI HGTwain_DisableDS(HGTwainDS ds) diff --git a/modules/twain_user/HGTwain.h b/modules/twain_user/HGTwain.h index ca6cdded..8062e184 100644 --- a/modules/twain_user/HGTwain.h +++ b/modules/twain_user/HGTwain.h @@ -54,7 +54,7 @@ HGEXPORT HGResult HGAPI HGTwain_UnloadDSM(HGTwainDSM dsm); * 1) 执行此函数后,TWAIN状态从2变为3 * 2) 调用该函数的线程需要有消息循环 */ -HGEXPORT HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm); +HGEXPORT HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm, HWND hwnd, HGDSEventFunc func, HGPointer param); /* 关闭DSM * 参数: @@ -150,8 +150,7 @@ HGEXPORT HGResult HGAPI HGTwain_GetCapability(HGTwainDS ds, HGUInt cap, HGInt* v * 说明: * 1) 执行此函数后,TWAIN状态从4变为5 */ -HGEXPORT HGResult HGAPI HGTwain_EnableDSUIOnly(HGTwainDS ds, HGBool showUI, HWND parent, - HGDSEventFunc func, HGPointer param); +HGEXPORT HGResult HGAPI HGTwain_EnableDSUIOnly(HGTwainDS ds, HGBool showUI, HWND parent); /* 启动DS * 参数: @@ -163,8 +162,7 @@ HGEXPORT HGResult HGAPI HGTwain_EnableDSUIOnly(HGTwainDS ds, HGBool showUI, HWND * 说明: * 1) 执行此函数后,TWAIN状态从4变为5 */ -HGEXPORT HGResult HGAPI HGTwain_EnableDS(HGTwainDS ds, HGBool showUI, HWND parent, - HGDSEventFunc func, HGPointer param); +HGEXPORT HGResult HGAPI HGTwain_EnableDS(HGTwainDS ds, HGBool showUI, HWND parent); /* 停止DS * 参数: diff --git a/modules/twain_user/HGTwainImpl.cpp b/modules/twain_user/HGTwainImpl.cpp index 2a691da3..54c961ec 100644 --- a/modules/twain_user/HGTwainImpl.cpp +++ b/modules/twain_user/HGTwainImpl.cpp @@ -1,9 +1,7 @@ #include "HGTwainImpl.hpp" #include "../base/HGInc.h" -extern HMODULE g_hInst; - -ULONG HGTwainDSMImpl::m_nRefCount = 0; +std::map HGTwainDSMImpl::m_mapWnd; HGTwainDSMImpl::HGTwainDSMImpl() { @@ -11,34 +9,15 @@ HGTwainDSMImpl::HGTwainDSMImpl() m_pDSMProc = NULL; GetIdentity(); m_hWnd = NULL; + m_oldWndProc = NULL; + m_dsEventFunc = NULL; + m_dsEventParam = NULL; m_DSMOpen = HGFALSE; - - if (0 == m_nRefCount) - { - WNDCLASSW wndcls; - wndcls.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - wndcls.lpfnWndProc = WndProc; - wndcls.cbClsExtra = 0; - wndcls.cbWndExtra = 0; - wndcls.hInstance = g_hInst; - wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wndcls.hCursor = LoadCursor(NULL, IDC_ARROW); - wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - wndcls.lpszMenuName = NULL; - wndcls.lpszClassName = L"TwainDSMWnd"; - ATOM atom = RegisterClassW(&wndcls); - assert(0 != atom); - } - ++m_nRefCount; } HGTwainDSMImpl::~HGTwainDSMImpl() { - --m_nRefCount; - if (0 == m_nRefCount) - { - UnregisterClassW(L"TwainDSMWnd", g_hInst); - } + UnloadDSM(); } HGResult HGTwainDSMImpl::LoadDSM() @@ -82,26 +61,24 @@ HGResult HGTwainDSMImpl::UnloadDSM() return HGBASE_ERR_OK; } -HGResult HGTwainDSMImpl::OpenDSM() +HGResult HGTwainDSMImpl::OpenDSM(HWND hwnd, HGDSEventFunc func, HGPointer param) { - if (NULL == m_pDSMProc || m_DSMOpen) + if (NULL == m_pDSMProc || m_DSMOpen || NULL == hwnd || NULL == func) { return HGBASE_ERR_FAIL; } - assert(NULL == m_hWnd); - HWND hWnd = CreateWindowExW(0, TEXT("TwainDSMWnd"), NULL, WS_OVERLAPPEDWINDOW, -1, -1, 1, 1, NULL, (HMENU)0, g_hInst, NULL); - assert(NULL != hWnd); - SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this); - - USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF)&hWnd); + USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF)&hwnd); if (TWRC_SUCCESS != ret) { - DestroyWindow(hWnd); return HGBASE_ERR_FAIL; } - m_hWnd = hWnd; + m_hWnd = hwnd; + m_mapWnd[m_hWnd] = this; + m_oldWndProc = (WNDPROC)SetWindowLongPtrW(m_hWnd, GWLP_WNDPROC, (LONG_PTR)NewWndProc); + m_dsEventFunc = func; + m_dsEventParam = param; m_DSMOpen = HGTRUE; // 获取DS列表 @@ -141,8 +118,20 @@ HGResult HGTwainDSMImpl::CloseDSM() m_DSList.clear(); m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&m_hWnd); - DestroyWindow(m_hWnd); + SetWindowLongPtrW(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_oldWndProc); + m_oldWndProc = NULL; + std::map::iterator iter; + for (iter = m_mapWnd.begin(); iter != m_mapWnd.end(); ++iter) + { + if (iter->first == m_hWnd) + { + m_mapWnd.erase(iter); + break; + } + } m_hWnd = NULL; + m_dsEventFunc = NULL; + m_dsEventParam = NULL; m_DSMOpen = HGFALSE; return HGBASE_ERR_OK; } @@ -436,9 +425,9 @@ HGResult HGTwainDSMImpl::GetCapability(HGTwainDSImpl* ds, HGUInt cap, HGInt* val return HGBASE_ERR_FAIL; } -HGResult HGTwainDSMImpl::EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND parent, HGDSEventFunc func, HGPointer param) +HGResult HGTwainDSMImpl::EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND parent) { - if (NULL == ds || NULL == func) + if (NULL == ds) { return HGBASE_ERR_INVALIDARG; } @@ -463,8 +452,6 @@ HGResult HGTwainDSMImpl::EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND p m_DSList[i].showUI = showUI; m_DSList[i].parent = parent; - m_DSList[i].func = func; - m_DSList[i].param = param; m_DSList[i].enable = HGTRUE; return HGBASE_ERR_OK; } @@ -473,9 +460,9 @@ HGResult HGTwainDSMImpl::EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND p return HGBASE_ERR_FAIL; } -HGResult HGTwainDSMImpl::EnableDS(HGTwainDSImpl* ds, HGBool showUI, HWND parent, HGDSEventFunc func, HGPointer param) +HGResult HGTwainDSMImpl::EnableDS(HGTwainDSImpl* ds, HGBool showUI, HWND parent) { - if (NULL == ds || NULL == func) + if (NULL == ds) { return HGBASE_ERR_INVALIDARG; } @@ -500,8 +487,6 @@ HGResult HGTwainDSMImpl::EnableDS(HGTwainDSImpl* ds, HGBool showUI, HWND parent, m_DSList[i].showUI = showUI; m_DSList[i].parent = parent; - m_DSList[i].func = func; - m_DSList[i].param = param; m_DSList[i].enable = HGTRUE; return HGBASE_ERR_OK; } @@ -528,13 +513,11 @@ HGResult HGTwainDSMImpl::DisableDS(HGTwainDSImpl* ds) TW_USERINTERFACE twUI; twUI.ShowUI = (TW_BOOL)m_DSList[i].showUI; - twUI.hParent = (TW_HANDLE)m_DSList[i].param; + twUI.hParent = (TW_HANDLE)m_DSList[i].parent; m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &twUI); m_DSList[i].showUI = HGFALSE; m_DSList[i].parent = NULL; - m_DSList[i].func = NULL; - m_DSList[i].param = NULL; m_DSList[i].enable = HGFALSE; return HGBASE_ERR_OK; } @@ -658,40 +641,40 @@ void HGTwainDSMImpl::GetIdentity() strcpy(m_AppId.ProductName, "MyTwain"); } -LRESULT CALLBACK HGTwainDSMImpl::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +LRESULT CALLBACK HGTwainDSMImpl::NewWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - HGTwainDSMImpl *p = (HGTwainDSMImpl *)GetWindowLongPtrW(hWnd, GWLP_USERDATA); - if (NULL != p) - { - MSG msg2 = { 0 }; - msg2.hwnd = hWnd; - msg2.message = msg; - msg2.wParam = wParam; - msg2.lParam = lParam; + HGTwainDSMImpl* p = m_mapWnd[hWnd]; + assert(NULL != p); + + MSG msg2 = { 0 }; + msg2.hwnd = hWnd; + msg2.message = msg; + msg2.wParam = wParam; + msg2.lParam = lParam; - for (int i = 0; i < (int)p->m_DSList.size(); ++i) + for (int i = 0; i < (int)p->m_DSList.size(); ++i) + { + if (p->m_DSList[i].enable) { - if (p->m_DSList[i].enable) + TW_EVENT twEvent; + twEvent.pEvent = (TW_MEMREF)&msg2; + twEvent.TWMessage = MSG_NULL; + USHORT ret = p->m_pDSMProc(&p->m_AppId, &p->m_DSList[i].ds, DG_CONTROL, DAT_EVENT, + MSG_PROCESSEVENT, (TW_MEMREF)&twEvent); + if (TWRC_DSEVENT == ret) { - TW_EVENT twEvent; - twEvent.pEvent = (TW_MEMREF)&msg2; - twEvent.TWMessage = MSG_NULL; - USHORT ret = p->m_pDSMProc(&p->m_AppId, &p->m_DSList[i].ds, DG_CONTROL, DAT_EVENT, - MSG_PROCESSEVENT, (TW_MEMREF)&twEvent); - if (TWRC_DSEVENT == ret && NULL != p->m_DSList[i].func) - { - HGUInt event = HGTWAIN_DSEVENT_UNKNOWN; - if (MSG_XFERREADY == twEvent.TWMessage) - event = HGTWAIN_DSEVENT_XFERREADY; - else if (MSG_CLOSEDSREQ == twEvent.TWMessage) - event = HGTWAIN_DSEVENT_CLOSEDSREQ; - else if (MSG_CLOSEDSOK == twEvent.TWMessage) - event = HGTWAIN_DSEVENT_CLOSEDSOK; - p->m_DSList[i].func((HGTwainDS)&p->m_DSList[i], event, p->m_DSList[i].param); - } + HGUInt event = HGTWAIN_DSEVENT_UNKNOWN; + if (MSG_XFERREADY == twEvent.TWMessage) + event = HGTWAIN_DSEVENT_XFERREADY; + else if (MSG_CLOSEDSREQ == twEvent.TWMessage) + event = HGTWAIN_DSEVENT_CLOSEDSREQ; + else if (MSG_CLOSEDSOK == twEvent.TWMessage) + event = HGTWAIN_DSEVENT_CLOSEDSOK; + + p->m_dsEventFunc((HGTwainDS)&p->m_DSList[i], event, p->m_dsEventParam); } } } - return DefWindowProc(hWnd, msg, wParam, lParam); + return CallWindowProcW(p->m_oldWndProc, hWnd, msg, wParam, lParam); } \ No newline at end of file diff --git a/modules/twain_user/HGTwainImpl.hpp b/modules/twain_user/HGTwainImpl.hpp index 4b2434d1..58143c3e 100644 --- a/modules/twain_user/HGTwainImpl.hpp +++ b/modules/twain_user/HGTwainImpl.hpp @@ -5,6 +5,7 @@ #include "../base/HGDll.h" #include "twain.h" #include +#include struct HGTwainDSImpl { @@ -15,8 +16,6 @@ struct HGTwainDSImpl open = HGFALSE; showUI = HGFALSE; parent = NULL; - func = NULL; - param = NULL; enable = HGFALSE; } @@ -25,8 +24,6 @@ struct HGTwainDSImpl HGBool open; HGBool showUI; HWND parent; - HGDSEventFunc func; - HGPointer param; HGBool enable; }; @@ -38,7 +35,7 @@ public: HGResult LoadDSM(); HGResult UnloadDSM(); - HGResult OpenDSM(); + HGResult OpenDSM(HWND hwnd, HGDSEventFunc func, HGPointer param); HGResult CloseDSM(); HGResult GetDSList(HGTwainDSImpl** ds, HGUInt* size); @@ -50,8 +47,8 @@ public: HGResult SetCapability(HGTwainDSImpl* ds, HGUInt cap, HGInt value); HGResult GetCapability(HGTwainDSImpl* ds, HGUInt cap, HGInt* value); - HGResult EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND parent, HGDSEventFunc func, HGPointer param); - HGResult EnableDS(HGTwainDSImpl* ds, HGBool showUI, HWND parent, HGDSEventFunc func, HGPointer param); + HGResult EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND parent); + HGResult EnableDS(HGTwainDSImpl* ds, HGBool showUI, HWND parent); HGResult DisableDS(HGTwainDSImpl* ds); HGResult ImageNativeXfer(HGTwainDSImpl* ds, HGUInt type, HGUInt origin, HGImage* image); HGResult EndXfer(HGTwainDSImpl* ds, HGUInt* count); @@ -59,14 +56,17 @@ public: private: void GetIdentity(); - static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK NewWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); private: - static ULONG m_nRefCount; HGDll m_hDll; DSMENTRYPROC m_pDSMProc; TW_IDENTITY m_AppId; HWND m_hWnd; + static std::map m_mapWnd; + WNDPROC m_oldWndProc; + HGDSEventFunc m_dsEventFunc; + HGPointer m_dsEventParam; HGBool m_DSMOpen; std::vector m_DSList; }; diff --git a/modules/twain_user/dllmain.cpp b/modules/twain_user/dllmain.cpp index baa31637..7a7e0bb4 100644 --- a/modules/twain_user/dllmain.cpp +++ b/modules/twain_user/dllmain.cpp @@ -1,20 +1,16 @@ #include -HMODULE g_hInst = NULL; - BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - g_hInst = hModule; break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - g_hInst = NULL; break; }