code_app/modules/twain_user/HGTwainImpl.cpp

680 lines
14 KiB
C++
Raw Normal View History

2022-05-03 10:25:52 +00:00
#include "HGTwainImpl.hpp"
#include "../base/HGInc.h"
2022-07-21 08:20:51 +00:00
std::map<HWND, HGTwainDSMImpl*> HGTwainDSMImpl::m_mapWnd;
2022-05-03 10:25:52 +00:00
HGTwainDSMImpl::HGTwainDSMImpl()
{
m_hDll = NULL;
m_pDSMProc = NULL;
GetIdentity();
m_hWnd = NULL;
2022-07-21 08:20:51 +00:00
m_oldWndProc = NULL;
m_dsEventFunc = NULL;
m_dsEventParam = NULL;
2022-05-03 10:25:52 +00:00
m_DSMOpen = HGFALSE;
}
HGTwainDSMImpl::~HGTwainDSMImpl()
{
2022-07-21 08:20:51 +00:00
UnloadDSM();
2022-05-03 10:25:52 +00:00
}
HGResult HGTwainDSMImpl::LoadDSM()
{
if (NULL != m_pDSMProc)
{
return HGBASE_ERR_FAIL;
}
assert(NULL == m_hDll);
HGBase_CreateDll("twain_32.dll", &m_hDll);
if (NULL == m_hDll)
{
return HGBASE_ERR_FAIL;
}
HGBase_GetDllProcAddress(m_hDll, MAKEINTRESOURCEA(1), (HGPointer*)&m_pDSMProc);
if (NULL == m_pDSMProc)
{
HGBase_DestroyDll(m_hDll);
m_hDll = NULL;
return HGBASE_ERR_FAIL;
}
return HGBASE_ERR_OK;
}
HGResult HGTwainDSMImpl::UnloadDSM()
{
if (NULL == m_pDSMProc)
{
return HGBASE_ERR_FAIL;
}
// 先必须关闭DSM
CloseDSM();
m_pDSMProc = NULL;
HGBase_DestroyDll(m_hDll);
m_hDll = NULL;
return HGBASE_ERR_OK;
}
2022-07-21 08:20:51 +00:00
HGResult HGTwainDSMImpl::OpenDSM(HWND hwnd, HGDSEventFunc func, HGPointer param)
2022-05-03 10:25:52 +00:00
{
2022-07-21 08:20:51 +00:00
if (NULL == m_pDSMProc || m_DSMOpen || NULL == hwnd || NULL == func)
2022-05-03 10:25:52 +00:00
{
return HGBASE_ERR_FAIL;
}
2022-07-21 08:20:51 +00:00
USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF)&hwnd);
2022-05-03 10:25:52 +00:00
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
2022-07-21 08:20:51 +00:00
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;
2022-05-03 10:25:52 +00:00
m_DSMOpen = HGTRUE;
// 获取DS列表
TW_IDENTITY ds;
ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, &ds);
if (TWRC_SUCCESS == ret)
{
HGTwainDSImpl dsImpl(this);
memcpy(&dsImpl.ds, &ds, sizeof(TW_IDENTITY));
m_DSList.push_back(dsImpl);
while (TWRC_SUCCESS == m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &ds))
{
HGTwainDSImpl dsImpl(this);
memcpy(&dsImpl.ds, &ds, sizeof(TW_IDENTITY));
m_DSList.push_back(dsImpl);
}
}
return HGBASE_ERR_OK;
}
HGResult HGTwainDSMImpl::CloseDSM()
{
if (!m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
// 先必须关闭DS
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
CloseDS(&m_DSList[i]);
}
// 清理DS列表
m_DSList.clear();
m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&m_hWnd);
2022-07-21 08:20:51 +00:00
SetWindowLongPtrW(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_oldWndProc);
m_oldWndProc = NULL;
std::map<HWND, HGTwainDSMImpl*>::iterator iter;
for (iter = m_mapWnd.begin(); iter != m_mapWnd.end(); ++iter)
{
if (iter->first == m_hWnd)
{
m_mapWnd.erase(iter);
break;
}
}
2022-05-03 10:25:52 +00:00
m_hWnd = NULL;
2022-07-21 08:20:51 +00:00
m_dsEventFunc = NULL;
m_dsEventParam = NULL;
2022-05-03 10:25:52 +00:00
m_DSMOpen = HGFALSE;
return HGBASE_ERR_OK;
}
HGResult HGTwainDSMImpl::GetDSList(HGTwainDSImpl** ds, HGUInt* size)
{
if (NULL == ds || NULL == size || 0 == *size)
{
return HGBASE_ERR_INVALIDARG;
}
if (!m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
HGUInt count = 0;
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
ds[i] = &m_DSList[i];
++count;
if (count >= *size)
{
break;
}
}
*size = count;
return HGBASE_ERR_OK;
}
HGResult HGTwainDSMImpl::GetDefaultDS(HGTwainDSImpl** ds)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
if (!m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
assert(NULL != m_pDSMProc);
TW_IDENTITY defDS;
USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &defDS);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (0 == memcmp(&defDS, &m_DSList[i].ds, sizeof(TW_IDENTITY)))
{
*ds = &m_DSList[i];
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::SelectDS(HGTwainDSImpl** ds)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
if (!m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
assert(NULL != m_pDSMProc);
TW_IDENTITY selectDS;
USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &selectDS);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (0 == memcmp(&selectDS, &m_DSList[i].ds, sizeof(TW_IDENTITY)))
{
*ds = &m_DSList[i];
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::GetDSName(HGTwainDSImpl* ds, HGChar* name, HGUInt maxLen)
{
if (NULL == ds || NULL == name || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
if (!m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
strcpy_s(name, maxLen, m_DSList[i].ds.ProductName);
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::OpenDS(HGTwainDSImpl* ds)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
if (!m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (m_DSList[i].open)
{
return HGBASE_ERR_FAIL;
}
USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &m_DSList[i].ds);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
m_DSList[i].open = HGTRUE;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::CloseDS(HGTwainDSImpl* ds)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].open)
{
return HGBASE_ERR_FAIL;
}
DisableDS(ds);
m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, (TW_MEMREF)&m_DSList[i].ds);
m_DSList[i].open = HGFALSE;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::SetCapability(HGTwainDSImpl* ds, HGUInt cap, HGInt value)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].open)
{
return HGBASE_ERR_FAIL;
}
TW_UINT16 cap2 = 0;
if (HGTWAIN_DSCAP_DUPLEX == cap)
cap2 = CAP_DUPLEX;
else if (HGTWAIN_DSCAP_DUPLEXENABLED == cap)
cap2 = CAP_DUPLEXENABLED;
else if (HGTWAIN_DSCAP_XFERCOUNT == cap)
cap2 = CAP_XFERCOUNT;
if (0 == cap2)
{
return HGBASE_ERR_FAIL;
}
TW_CAPABILITY twCap;
twCap.Cap = (TW_UINT16)cap2;
twCap.ConType = TWON_ONEVALUE;
twCap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));
if (NULL == twCap.hContainer)
{
return HGBASE_ERR_FAIL;
}
pTW_ONEVALUE pVal = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
assert(NULL != pVal);
pVal->ItemType = TWTY_INT32;
pVal->Item = (TW_UINT32)value;
GlobalUnlock(twCap.hContainer);
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_CAPABILITY, MSG_SET, &twCap);
if (TWRC_SUCCESS != ret)
{
GlobalFree(twCap.hContainer);
return HGBASE_ERR_FAIL;
}
GlobalFree(twCap.hContainer);
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::GetCapability(HGTwainDSImpl* ds, HGUInt cap, HGInt* value)
{
if (NULL == ds || NULL == value)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].open)
{
return HGBASE_ERR_FAIL;
}
TW_UINT16 cap2 = 0;
if (HGTWAIN_DSCAP_DUPLEX == cap)
cap2 = CAP_DUPLEX;
else if (HGTWAIN_DSCAP_DUPLEXENABLED == cap)
cap2 = CAP_DUPLEXENABLED;
else if (HGTWAIN_DSCAP_XFERCOUNT == cap)
cap2 = CAP_XFERCOUNT;
if (0 == cap2)
{
return HGBASE_ERR_FAIL;
}
TW_CAPABILITY twCap;
twCap.Cap = (TW_UINT16)cap2;
twCap.ConType = TWON_ONEVALUE;
twCap.hContainer = NULL;
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_CAPABILITY, MSG_GETCURRENT, &twCap);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
assert(NULL != twCap.hContainer);
pTW_ONEVALUE pVal = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
assert(NULL != pVal);
*value = pVal->Item;
GlobalUnlock(twCap.hContainer);
GlobalFree(twCap.hContainer);
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
2022-07-21 08:20:51 +00:00
HGResult HGTwainDSMImpl::EnableDSUIOnly(HGTwainDSImpl* ds, HGBool showUI, HWND parent)
2022-05-03 10:25:52 +00:00
{
2022-07-21 08:20:51 +00:00
if (NULL == ds)
2022-05-03 10:25:52 +00:00
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].open || m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_USERINTERFACE twUI;
twUI.ShowUI = (TW_BOOL)showUI;
twUI.hParent = (TW_HANDLE)parent;
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDSUIONLY, (TW_MEMREF)&twUI);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
m_DSList[i].showUI = showUI;
m_DSList[i].parent = parent;
m_DSList[i].enable = HGTRUE;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
2022-07-21 08:20:51 +00:00
HGResult HGTwainDSMImpl::EnableDS(HGTwainDSImpl* ds, HGBool showUI, HWND parent)
2022-05-03 10:25:52 +00:00
{
2022-07-21 08:20:51 +00:00
if (NULL == ds)
2022-05-03 10:25:52 +00:00
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].open || m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_USERINTERFACE twUI;
twUI.ShowUI = (TW_BOOL)showUI;
twUI.hParent = (TW_HANDLE)parent;
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, (TW_MEMREF)&twUI);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
m_DSList[i].showUI = showUI;
m_DSList[i].parent = parent;
m_DSList[i].enable = HGTRUE;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::DisableDS(HGTwainDSImpl* ds)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_USERINTERFACE twUI;
twUI.ShowUI = (TW_BOOL)m_DSList[i].showUI;
2022-07-21 08:20:51 +00:00
twUI.hParent = (TW_HANDLE)m_DSList[i].parent;
2022-05-03 10:25:52 +00:00
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].enable = HGFALSE;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::ImageNativeXfer(HGTwainDSImpl* ds, HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == ds || NULL == image)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_IMAGEINFO info;
if (TWRC_SUCCESS != m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF)&info))
{
return HGBASE_ERR_FAIL;
}
HANDLE hMem = NULL;
if (TWRC_XFERDONE != m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hMem))
{
return HGBASE_ERR_FAIL;
}
HGResult ret = HGBase_CreateImageFromDIB(hMem, NULL, type, origin, image);
GlobalFree(hMem);
return ret;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::EndXfer(HGTwainDSImpl* ds, HGUInt* count)
{
if (NULL == ds || NULL == count)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_PENDINGXFERS twPend;
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF)&twPend);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
*count = twPend.Count;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainDSMImpl::Reset(HGTwainDSImpl* ds)
{
if (NULL == ds)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == &m_DSList[i])
{
if (!m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_PENDINGXFERS twPend;
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, (TW_MEMREF)&twPend);
if (TWRC_SUCCESS != ret)
{
return HGBASE_ERR_FAIL;
}
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
void HGTwainDSMImpl::GetIdentity()
{
m_AppId.Id = 0; // Initialize to 0 (Source Manager
// will assign real value)
m_AppId.Version.MajorNum = 3; //Your app's version number
m_AppId.Version.MinorNum = 8;
m_AppId.Version.Language = TWLG_USA;
m_AppId.Version.Country = TWCY_USA;
strcpy(m_AppId.Version.Info, "3.8");
m_AppId.ProtocolMajor = TWON_PROTOCOLMAJOR;
m_AppId.ProtocolMinor = TWON_PROTOCOLMINOR;
m_AppId.SupportedGroups = DG_IMAGE | DG_CONTROL;
strcpy(m_AppId.Manufacturer, "MICSS");
strcpy(m_AppId.ProductFamily, "Generic");
strcpy(m_AppId.ProductName, "MyTwain");
}
2022-07-21 08:20:51 +00:00
LRESULT CALLBACK HGTwainDSMImpl::NewWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
2022-05-03 10:25:52 +00:00
{
2022-07-21 08:20:51 +00:00
HGTwainDSMImpl* p = m_mapWnd[hWnd];
assert(NULL != p);
MSG msg2 = { 0 };
msg2.hwnd = hWnd;
msg2.message = msg;
msg2.wParam = wParam;
msg2.lParam = lParam;
2022-05-03 10:25:52 +00:00
2022-07-21 08:20:51 +00:00
for (int i = 0; i < (int)p->m_DSList.size(); ++i)
{
if (p->m_DSList[i].enable)
2022-05-03 10:25:52 +00:00
{
2022-07-21 08:20:51 +00:00
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)
2022-05-03 10:25:52 +00:00
{
2022-07-21 08:20:51 +00:00
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);
2022-05-03 10:25:52 +00:00
}
}
}
2022-07-21 08:20:51 +00:00
return CallWindowProcW(p->m_oldWndProc, hWnd, msg, wParam, lParam);
2022-05-03 10:25:52 +00:00
}