HGGitLab

Commit c572ae38 authored by luoliangyi's avatar luoliangyi

增加日志记录功能

parent e2e55517
......@@ -10,9 +10,11 @@
#include "HGEvent.h"
#include "HGDll.h"
#include "HGLog.h"
#include "HGConsole.h"
#include "HGBuffer.h"
#include "HGImage.h"
#include "HGThread.h"
#include "HGUtility.h"
#include "HGInfo.h"
#endif /* __HGBASE_H__ */
\ No newline at end of file
#include "HGConsole.h"
#include "HGInc.h"
struct HGConsoleImpl
{
HGConsoleImpl()
{
#if defined(HG_CMP_MSC)
m_bAllocConsole = FALSE;
m_hConsole = INVALID_HANDLE_VALUE;
#endif
}
~HGConsoleImpl()
{
#if defined(HG_CMP_MSC)
if (INVALID_HANDLE_VALUE != m_hConsole)
m_hConsole = INVALID_HANDLE_VALUE;
if (m_bAllocConsole)
{
FreeConsole();
m_bAllocConsole = FALSE;
}
#endif
}
#if defined(HG_CMP_MSC)
BOOL m_bAllocConsole;
HANDLE m_hConsole;
#endif
};
HGResult HGAPI HGBase_OpenConsole(HGConsole* console)
{
if (NULL == console)
{
return HGBASE_ERR_INVALIDARG;
}
HGConsoleImpl* consoleImpl = new HGConsoleImpl;
#if defined(HG_CMP_MSC)
consoleImpl->m_bAllocConsole = AllocConsole();
consoleImpl->m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
*console = (HGConsole)consoleImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_CloseConsole(HGConsole console)
{
if (NULL == console)
{
return HGBASE_ERR_INVALIDARG;
}
HGConsoleImpl* consoleImpl = (HGConsoleImpl*)console;
delete consoleImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_WriteConsole(HGConsole console, const HGChar* info)
{
if (NULL == console || NULL == info || '\0' == *info)
{
return HGBASE_ERR_INVALIDARG;
}
HGConsoleImpl* consoleImpl = (HGConsoleImpl*)console;
#if defined(HG_CMP_MSC)
DWORD dwNumberOfCharsWritten;
WriteConsoleA(consoleImpl->m_hConsole, info, (DWORD)strlen(info), &dwNumberOfCharsWritten, NULL);
WriteConsoleA(consoleImpl->m_hConsole, "\r\n", (DWORD)strlen("\r\n"), &dwNumberOfCharsWritten, NULL);
#else
printf(info);
printf("\n");
#endif
return HGBASE_ERR_OK;
}
\ No newline at end of file
#ifndef __HGCONSOLE_H__
#define __HGCONSOLE_H__
#include "HGDef.h"
#include "HGBaseErr.h"
HG_DECLARE_HANDLE(HGConsole);
/* 开启控制台
* 参数:
* 1) log: out, 控制台句柄
* 说明:
*/
HGEXTERN_C HGResult HGAPI HGBase_OpenConsole(HGConsole *console);
/* 关闭控制台
* 参数:
* 1) log: in, 控制台句柄
* 说明:
*/
HGEXTERN_C HGResult HGAPI HGBase_CloseConsole(HGConsole console);
/* 写控制台信息
* 参数:
* 1) log: in, 控制台句柄
* 2) info: in, 信息, 一次一行, info无需加换行符
* 说明:
* 1) 该函数不是线程安全的, 在不同线程调用的时候, 需要加锁
*/
HGEXTERN_C HGResult HGAPI HGBase_WriteConsole(HGConsole console, const HGChar* info);
#endif /* __HGCONSOLE_H__ */
\ No newline at end of file
......@@ -84,6 +84,8 @@ typedef HGUInt HGResult;
#define HGAPI
#endif
#define HGAPIV __cdecl
#define HG_DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
typedef struct
......
#include "HGInfo.h"
#include "HGInfoImpl.hpp"
#include "HGInc.h"
extern HGInfoImpl* g_infoImpl;
HGResult HGAPIV HGBase_WriteInfo(HGUInt type, const HGChar* format, ...)
{
if (NULL == g_infoImpl)
return HGBASE_ERR_FAIL;
char buf[1024] = { 0 };
va_list va;
va_start(va, format);
vsprintf(buf, format, va);
va_end(va);
return g_infoImpl->Write(type, buf);
}
\ No newline at end of file
#ifndef __HGINFO_H__
#define __HGINFO_H__
#include "HGDef.h"
#include "HGBaseErr.h"
/* 致命错误 */
#define HGBASE_INFOTYPE_FATAL 1L
/* 一般错误 */
#define HGBASE_INFOTYPE_ERROR 2L
/* 警告 */
#define HGBASE_INFOTYPE_WARNING 4L
/* 一般描述信息 */
#define HGBASE_INFOTYPE_DESC 8L
/* 调试信息 */
#define HGBASE_INFOTYPE_DEBUG 16L
/* 写日志/控制台信息
* 参数:
* 1) type: in, 信息类型, 参见HGBASE_INFOTYPE_*
* 2) format: in, 信息格式
* 说明:
* 1) 信息的完整输出行: [日期-时间] [进程号/线程号] [信息类型] [信息]
* 2) 信息的实际输出行取决于HGGlobal.ini的配置
*/
HGEXTERN_C HGResult HGAPIV HGBase_WriteInfo(HGUInt type, const HGChar* format, ...);
#endif /* __HGINFO_H__ */
\ No newline at end of file
#include "HGInfoImpl.hpp"
#include "HGInfo.h"
#include "HGInc.h"
#include "HGUtility.h"
#include <string>
#include <vector>
HGInfoImpl::HGInfoImpl()
{
HGBase_CreateLock(&m_lock);
m_log = NULL;
m_console = NULL;
m_type = 0;
m_showTime = HGFALSE;
m_showId = HGFALSE;
m_showType = HGFALSE;
Load();
}
HGInfoImpl::~HGInfoImpl()
{
HGBase_CloseConsole(m_console);
m_console = NULL;
HGBase_CloseLog(m_log);
m_log = NULL;
HGBase_DestroyLock(m_lock);
m_lock = NULL;
}
HGResult HGInfoImpl::Write(HGUInt type, const HGChar* info)
{
if (HGBASE_INFOTYPE_FATAL != type && HGBASE_INFOTYPE_ERROR != type
&& HGBASE_INFOTYPE_WARNING != type && HGBASE_INFOTYPE_DESC != type
&& HGBASE_INFOTYPE_DEBUG != type)
{
return HGBASE_ERR_INVALIDARG;
}
if (NULL == info || '\0' == *info)
{
return HGBASE_ERR_INVALIDARG;
}
if (0 == (type & m_type))
{
return HGBASE_ERR_FAIL;
}
char writeInfo[2048] = { 0 };
if (m_showTime)
{
timeb tb;
ftime(&tb);
struct tm* p = localtime(&tb.time);
char timeStr[64] = { 0 };
sprintf(timeStr, "[%04d/%02d/%02d-%02d:%02d:%02d.%03d]", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday,
p->tm_hour, p->tm_min, p->tm_sec, tb.millitm);
strcat(writeInfo, timeStr);
strcat(writeInfo, " ");
}
if (m_showId)
{
char idStr[32] = { 0 };
#if defined(HG_CMP_MSC)
sprintf(idStr, "[0x%08X/0x%08X]", GetCurrentProcessId(), GetCurrentThreadId());
#else
sprintf(idStr, "[0x%08X/0x%08X]", getpid(), pthread_self());
#endif
strcat(writeInfo, idStr);
strcat(writeInfo, " ");
}
if (m_showType)
{
char typeStr[24] = { 0 };
if (HGBASE_INFOTYPE_FATAL == type)
sprintf(typeStr, "[%s]", "FAT");
else if (HGBASE_INFOTYPE_ERROR == type)
sprintf(typeStr, "[%s]", "ERR");
else if (HGBASE_INFOTYPE_WARNING == type)
sprintf(typeStr, "[%s]", "WAR");
else if (HGBASE_INFOTYPE_DESC == type)
sprintf(typeStr, "[%s]", "DES");
else
sprintf(typeStr, "[%s]", "DEB");
strcat(writeInfo, typeStr);
strcat(writeInfo, " ");
}
strcat(writeInfo, info);
HGBase_EnterLock(m_lock);
HGBase_WriteLog(m_log, writeInfo);
HGBase_WriteConsole(m_console, writeInfo);
HGBase_LeaveLock(m_lock);
return HGBASE_ERR_OK;
}
void HGInfoImpl::Load()
{
HGChar cfgPath[256] = {0};
HGBase_GetConfigPath(cfgPath, 256);
strcat(cfgPath, "HGGlobal.ini");
HGBool writeLog;
HGBase_GetProfileInt(cfgPath, "Info", "writeLog", 0, &writeLog);
HGBool writeConsole;
HGBase_GetProfileInt(cfgPath, "Info", "writeConsole", 0, &writeConsole);
HGUInt defType = HGBASE_INFOTYPE_FATAL | HGBASE_INFOTYPE_ERROR | HGBASE_INFOTYPE_WARNING
| HGBASE_INFOTYPE_DESC | HGBASE_INFOTYPE_DEBUG;
HGBase_GetProfileInt(cfgPath, "Info", "type", (HGInt)defType, (HGInt *)&m_type);
HGBase_GetProfileInt(cfgPath, "Info", "showTime", 1, &m_showTime);
HGBase_GetProfileInt(cfgPath, "Info", "showId", 0, &m_showId);
HGBase_GetProfileInt(cfgPath, "Info", "showType", 1, &m_showType);
if (writeLog)
{
HGChar logPath[256];
HGBase_GetLogFilePath(logPath, 256);
HGChar processName[256];
HGBase_GetProcessName(processName, 256);
strcat(logPath, processName);
HGBase_CreateDir(logPath);
timeb tb;
ftime(&tb);
struct tm* p = localtime(&tb.time);
char fileName[256];
#if defined(HG_CMP_MSC)
sprintf(fileName, "\\%04d%02d%02d.log", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
#else
sprintf(fileName, "/%04d%02d%02d.log", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
#endif
strcat(logPath, fileName);
HGBase_OpenLog(logPath, &m_log);
}
if (writeConsole)
{
HGBase_OpenConsole(&m_console);
}
}
\ No newline at end of file
#ifndef __HGINFOIMPL_HPP__
#define __HGINFOIMPL_HPP__
#include "HGLog.h"
#include "HGConsole.h"
#include "HGLock.h"
class HGInfoImpl
{
public:
HGInfoImpl();
~HGInfoImpl();
HGResult Write(HGUInt type, const HGChar* info);
private:
void Load();
private:
HGLock m_lock;
HGLog m_log;
HGConsole m_console;
HGUInt m_type;
HGBool m_showTime;
HGBool m_showId;
HGBool m_showType;
};
#endif /* __HGINFOIMPL_HPP__ */
\ No newline at end of file
......@@ -5,7 +5,6 @@ struct HGLogImpl
{
HGLogImpl()
{
m_console = HGFALSE;
m_file = NULL;
}
......@@ -18,36 +17,29 @@ struct HGLogImpl
}
}
HGBool m_console;
FILE* m_file;
};
HGResult HGAPI HGBase_CreateLog(HGBool console, const HGChar* fileName, HGLog* log)
HGResult HGAPI HGBase_OpenLog(const HGChar* fileName, HGLog* log)
{
if (NULL == log)
if (NULL == fileName || NULL == log)
{
return HGBASE_ERR_INVALIDARG;
}
FILE* file = NULL;
if (NULL != fileName)
{
file = fopen((const char *)fileName, "a+");
FILE *file = fopen(fileName, "a+");
if (NULL == file)
{
return HGBASE_ERR_ACCESSDENIED;
}
}
HGLogImpl* logImpl = new HGLogImpl;
logImpl->m_console = console;
logImpl->m_file = file;
*log = (HGLog)logImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_DestroyLog(HGLog log)
HGResult HGAPI HGBase_CloseLog(HGLog log)
{
if (NULL == log)
{
......@@ -67,11 +59,6 @@ HGResult HGAPI HGBase_GetLogFileSize(HGLog log, HGLonglong* size)
}
HGLogImpl* logImpl = (HGLogImpl*)log;
if (NULL == logImpl->m_file)
{
return HGBASE_ERR_ACCESSDENIED;
}
#if defined(HG_CMP_MSC)
_fseeki64(logImpl->m_file, 0, SEEK_END);
*size = _ftelli64(logImpl->m_file);
......@@ -79,7 +66,6 @@ HGResult HGAPI HGBase_GetLogFileSize(HGLog log, HGLonglong* size)
fseeko64(logImpl->m_file, 0, SEEK_END);
*size = ftello64(logImpl->m_file);
#endif
return HGBASE_ERR_OK;
}
......@@ -90,34 +76,14 @@ HGResult HGAPI HGBase_WriteLog(HGLog log, const HGChar* info)
return HGBASE_ERR_INVALIDARG;
}
if (strlen((const char *)info) > 1024)
{
return HGBASE_ERR_INVALIDDATA;
}
timeb tb;
ftime(&tb);
struct tm* p = localtime(&tb.time);
char logInfo[1200];
sprintf(logInfo, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] %s\n", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday,
p->tm_hour, p->tm_min, p->tm_sec, tb.millitm, info);
HGLogImpl* logImpl = (HGLogImpl*)log;
if (logImpl->m_console)
{
printf("%s\n", logInfo);
}
if (NULL != logImpl->m_file)
{
#if defined(HG_CMP_MSC)
_fseeki64(logImpl->m_file, 0, SEEK_END);
#else
fseeko64(logImpl->m_file, 0, SEEK_END);
#endif
fputs(logInfo, logImpl->m_file);
fwrite(info, 1, strlen(info), logImpl->m_file);
fwrite("\n", 1, strlen("\n"), logImpl->m_file);
fflush(logImpl->m_file);
}
return HGBASE_ERR_OK;
}
\ No newline at end of file
......@@ -8,39 +8,34 @@ HG_DECLARE_HANDLE(HGLog);
/* 开启日志
* 参数:
* 1) console: in, 是否将日志输出到控制台
* 2) fileName: in, 日志文件名
* 3) log: out, 日志句柄
* 1) fileName: in, 文件名
* 2) log: out, 日志句柄
* 说明:
* 1) 当只想将日志输出到控制台时, console传HGTRUE, fileName传NULL
* 2) 当只想将日志输出到文件时, console传HGFALSE, fileName传文件名
* 3) 写日志文件的方式是追加写,一条日志一行
*/
HGEXTERN_C HGResult HGAPI HGBase_CreateLog(HGBool console, const HGChar* fileName, HGLog* log);
HGEXTERN_C HGResult HGAPI HGBase_OpenLog(const HGChar* fileName, HGLog* log);
/* 关闭日志
* 参数:
* 1) log: in, 日志句柄
* 说明:
*/
HGEXTERN_C HGResult HGAPI HGBase_DestroyLog(HGLog log);
HGEXTERN_C HGResult HGAPI HGBase_CloseLog(HGLog log);
/* 获取日志文件大小
* 参数:
* 1) log: in, 日志句柄
* 2) size: out, 日志文件大小
* 说明:
* 1) 每次写入日志后,可以用该函数检查日志文件的大小,当日志文件足够大时,可以关闭该日志句柄,在新的日志文件上重新打开
* 1) 每次写入日志信息后,可以用该函数检查日志文件的大小,当日志文件足够大时,可以关闭该日志句柄,在新的日志文件上重新打开
*/
HGEXTERN_C HGResult HGAPI HGBase_GetLogFileSize(HGLog log, HGLonglong* size);
/* 写入日志
/* 写日志信息
* 参数:
* 1) log: in, 日志句柄
* 2) info: in, 单条日志信息, 长度不能超过1024字节
* 2) info: in, 信息, 一次一行, info无需加换行符
* 说明:
* 1) 写日志文件的方式是追加写,一条日志一行
* 2) 该函数不是线程安全的, 在不同进程或不同线程调用的时候, 需要加锁
* 1) 该函数不是线程安全的, 在不同进程或不同线程调用的时候, 需要加锁
*/
HGEXTERN_C HGResult HGAPI HGBase_WriteLog(HGLog log, const HGChar* info);
......
This diff is collapsed.
......@@ -42,4 +42,40 @@ HGEXTERN_C HGResult HGAPI HGBase_GetUuid(HGChar* uuid, HGUInt maxLen);
*/
HGEXTERN_C HGResult HGAPI HGBase_GetTmpFileName(HGChar* fileName, HGUInt maxLen);
/* 获取配置文件路径
*/
HGEXTERN_C HGResult HGAPI HGBase_GetConfigPath(HGChar* configPath, HGUInt maxLen);
/* 获取日志文件路径
*/
HGEXTERN_C HGResult HGAPI HGBase_GetLogFilePath(HGChar* logFilePath, HGUInt maxLen);
/* 获取进程名
*/
HGEXTERN_C HGResult HGAPI HGBase_GetProcessName(HGChar* name, HGUInt maxLen);
/* 通过文件全路径获取文件名
*/
HGEXTERN_C HGResult HGAPI HGBase_GetFileName(const HGChar *filePath, HGChar* name, HGUInt maxLen);
/* 设置ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_SetProfileInt(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, HGInt value);
/* 设置ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_SetProfileString(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, const HGChar *value);
/* 获取ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_GetProfileInt(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, HGInt def, HGInt* value);
/* 获取ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_GetProfileString(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, const HGChar* def, HGChar* value, HGUInt maxLen);
#endif /* __HGUTILITY_H__ */
\ No newline at end of file
#include "HGDef.h"
#if defined(HG_CMP_MSC)
#include "HGInfoImpl.hpp"
#include "HGInc.h"
#include <combaseapi.h>
#include <gdiplus.h>
#include <assert.h>
static ULONG_PTR g_nToken = 0;
HGInfoImpl* g_infoImpl = NULL;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
......@@ -14,6 +19,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
Gdiplus::GdiplusStartupOutput output;
Gdiplus::GdiplusStartup(&g_nToken, &input, &output);
assert(0 != g_nToken);
g_infoImpl = new HGInfoImpl;
}
break;
case DLL_THREAD_ATTACH:
......@@ -22,6 +29,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
break;
case DLL_PROCESS_DETACH:
{
delete g_infoImpl;
g_infoImpl = NULL;
Gdiplus::GdiplusShutdown(g_nToken);
g_nToken = 0;
}
......@@ -30,3 +40,22 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
return TRUE;
}
#else
HGInfoImpl* g_infoImpl = NULL;
void __attribute__((constructor)) global_load(void);
void __attribute__((destructor)) global_unload(void);
void global_load(void)
{
g_infoImpl = new HGInfoImpl;
}
void global_unload(void)
{
delete g_infoImpl;
g_infoImpl = NULL;
}
#endif
\ No newline at end of file
......@@ -7,6 +7,7 @@ HGBase_Base64Decode
HGBase_DesEncrypt
HGBase_DesDecrypt
HGBase_MakeMd5
HGBase_CreateDll
......@@ -28,11 +29,17 @@ HGBase_LeaveLock
HGBase_OpenThread
HGBase_CloseThread
HGBase_CreateLog
HGBase_DestroyLog
HGBase_OpenLog
HGBase_CloseLog
HGBase_GetLogFileSize
HGBase_WriteLog
HGBase_OpenConsole
HGBase_CloseConsole
HGBase_WriteConsole
HGBase_WriteInfo
HGBase_GetTmpPath
HGBase_GetCurrentDir
HGBase_SetCurrentDir
......@@ -42,6 +49,14 @@ HGBase_DeleteFile
HGBase_GetModuleName
HGBase_GetUuid
HGBase_GetTmpFileName
HGBase_GetConfigPath
HGBase_GetLogFilePath
HGBase_GetProcessName
HGBase_GetFileName
HGBase_SetProfileInt
HGBase_SetProfileString
HGBase_GetProfileInt
HGBase_GetProfileString
HGBase_CreateBuffer
HGBase_CreateBufferFromData
......
......@@ -22,23 +22,27 @@
<None Include="HGBase.def" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\base\dllmain.cpp" />
<ClCompile Include="..\..\..\base\HGBase64.cpp" />
<ClCompile Include="..\..\..\base\HGBuffer.cpp" />
<ClCompile Include="..\..\..\base\HGConsole.cpp" />
<ClCompile Include="..\..\..\base\HGDes.cpp" />
<ClCompile Include="..\..\..\base\HGDll.cpp" />
<ClCompile Include="..\..\..\base\HGEvent.cpp" />
<ClCompile Include="..\..\..\base\HGImage.cpp" />
<ClCompile Include="..\..\..\base\HGInfo.cpp" />
<ClCompile Include="..\..\..\base\HGInfoImpl.cpp" />
<ClCompile Include="..\..\..\base\HGLock.cpp" />
<ClCompile Include="..\..\..\base\HGLog.cpp" />
<ClCompile Include="..\..\..\base\HGMd5.cpp" />
<ClCompile Include="..\..\..\base\HGThread.cpp" />
<ClCompile Include="..\..\..\base\HGUtility.cpp" />
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\base\HGBase.h" />
<ClInclude Include="..\..\..\base\HGBase64.h" />
<ClInclude Include="..\..\..\base\HGBaseErr.h" />
<ClInclude Include="..\..\..\base\HGConsole.h" />
<ClInclude Include="..\..\..\base\HGInc.h" />
<ClInclude Include="..\..\..\base\HGBuffer.h" />
<ClInclude Include="..\..\..\base\HGDef.h" />
......@@ -46,6 +50,8 @@
<ClInclude Include="..\..\..\base\HGDll.h" />
<ClInclude Include="..\..\..\base\HGEvent.h" />
<ClInclude Include="..\..\..\base\HGImage.h" />
<ClInclude Include="..\..\..\base\HGInfo.h" />
<ClInclude Include="..\..\..\base\HGInfoImpl.hpp" />
<ClInclude Include="..\..\..\base\HGLock.h" />
<ClInclude Include="..\..\..\base\HGLog.h" />
<ClInclude Include="..\..\..\base\HGMd5.h" />
......
......@@ -16,7 +16,6 @@ HGTwain_SetCapability
HGTwain_GetCapability
HGTwain_EnableDS
HGTwain_DisableDS
HGTwain_GetEvent
HGTwain_ImageNativeXfer
HGTwain_EndXfer
HGTwain_Reset
......@@ -22,6 +22,7 @@
<None Include="HGTwainUser.def" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\twain_user\dllmain.cpp" />
<ClCompile Include="..\..\..\twain_user\HGTwain.cpp" />
<ClCompile Include="..\..\..\twain_user\HGTwainImpl.cpp" />
</ItemGroup>
......
......@@ -124,6 +124,10 @@ BOOL CHGTestDlg::OnInitDialog()
HGImgFmt_SaveImage(image1, 0, NULL, 0, "D:\\11111.bmp");
HGImgFmt_SaveImage(image2, 0, NULL, 0, "D:\\22222.bmp");
#endif
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "Test: %d", 123456);
HGBase_WriteInfo(HGBASE_INFOTYPE_DEBUG, "Test: %d", 12345);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
......@@ -176,29 +180,6 @@ HCURSOR CHGTestDlg::OnQueryDragIcon()
return static_cast<HCURSOR>(m_hIcon);
}
BOOL CHGTestDlg::PreTranslateMessage(MSG* pMsg)
{
HGUInt event = 0;
HGTwain_GetEvent(m_dsm, m_ds, pMsg, &event);
if (HGTWAIN_EVENT_XFERREADY == event)
{
HGImage image = NULL;
HGTwain_ImageNativeXfer(m_dsm, m_ds, 0, HGBASE_IMGORIGIN_TOP, &image);
HGImgFmt_SaveImage(image, 0, NULL, 0, "D:\\1.bmp");
HGBase_DestroyImage(image);
}
else if (HGTWAIN_EVENT_CLOSEDSREQ == event)
{
HGTwain_UnloadDSM(m_dsm);
m_dsm = NULL;
}
return CDialogEx::PreTranslateMessage(pMsg);
}
void CHGTestDlg::OnBnClickedButton1()
{
if (NULL != m_dsm)
......@@ -207,11 +188,17 @@ void CHGTestDlg::OnBnClickedButton1()
}
HGTwain_LoadDSM(&m_dsm);
HGTwain_OpenDSM(m_dsm, m_hWnd);
HGTwain_GetDefaultDS(m_dsm, &m_ds);
HGTwain_OpenDSM(m_dsm);
HGTwain_SelectDS(m_dsm, &m_ds);
if (NULL == m_ds)
{
HGTwain_UnloadDSM(m_dsm);
m_dsm = NULL;
return;
}
HGTwain_OpenDS(m_dsm, m_ds);
HGTwain_EnableDS(m_dsm, m_ds, HGTRUE);
HGTwain_EnableDS(m_dsm, m_ds, HGTRUE, m_hWnd, DSEventCallback, this);
}
......@@ -220,3 +207,42 @@ void CHGTestDlg::OnBnClickedButton2()
HGTwain_UnloadDSM(m_dsm);
m_dsm = NULL;
}
void HGAPI CHGTestDlg::DSEventCallback(HGTwainDSM dsm, HGTwainDS ds, HGUInt event, HGPointer param)
{
CHGTestDlg* p = (CHGTestDlg*)param;
if (HGTWAIN_DSEVENT_XFERREADY == event)
{
ULONG idx = 0;
HGImage image = NULL;
HGTwain_ImageNativeXfer(p->m_dsm, p->m_ds, 0, HGBASE_IMGORIGIN_TOP, &image);
CStringA strName;
strName.Format("D:\\Twain_%u.bmp", idx);
HGImgFmt_SaveImage(image, 0, NULL, 0, strName);
HGBase_DestroyImage(image);
HGUInt count = 0;
HGTwain_EndXfer(p->m_dsm, p->m_ds, &count);
while (count != 0)
{
++idx;
HGImage image = NULL;
HGTwain_ImageNativeXfer(p->m_dsm, p->m_ds, 0, HGBASE_IMGORIGIN_TOP, &image);
CStringA strName;
strName.Format("D:\\Twain_%u.bmp", idx);
HGImgFmt_SaveImage(image, 0, NULL, 0, strName);
HGBase_DestroyImage(image);
HGTwain_EndXfer(p->m_dsm, p->m_ds, &count);
}
HGTwain_Reset(p->m_dsm, p->m_ds);
}
else if (HGTWAIN_DSEVENT_CLOSEDSREQ == event)
{
HGTwain_UnloadDSM(p->m_dsm);
p->m_dsm = NULL;
}
}
......@@ -23,6 +23,8 @@ protected:
HGTwainDSM m_dsm;
HGTwainDS m_ds;
static void HGAPI DSEventCallback(HGTwainDSM dsm, HGTwainDS ds, HGUInt event, HGPointer param);
// 实现
protected:
HICON m_hIcon;
......@@ -34,7 +36,6 @@ protected:
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
};
......@@ -10,9 +10,11 @@
#include "HGEvent.h"
#include "HGDll.h"
#include "HGLog.h"
#include "HGConsole.h"
#include "HGBuffer.h"
#include "HGImage.h"
#include "HGThread.h"
#include "HGUtility.h"
#include "HGInfo.h"
#endif /* __HGBASE_H__ */
\ No newline at end of file
#ifndef __HGCONSOLE_H__
#define __HGCONSOLE_H__
#include "HGDef.h"
#include "HGBaseErr.h"
HG_DECLARE_HANDLE(HGConsole);
/* 开启控制台
* 参数:
* 1) log: out, 控制台句柄
* 说明:
*/
HGEXTERN_C HGResult HGAPI HGBase_OpenConsole(HGConsole *console);
/* 关闭控制台
* 参数:
* 1) log: in, 控制台句柄
* 说明:
*/
HGEXTERN_C HGResult HGAPI HGBase_CloseConsole(HGConsole console);
/* 写控制台信息
* 参数:
* 1) log: in, 控制台句柄
* 2) info: in, 信息, 一次一行, info无需加换行符
* 说明:
* 1) 该函数不是线程安全的, 在不同线程调用的时候, 需要加锁
*/
HGEXTERN_C HGResult HGAPI HGBase_WriteConsole(HGConsole console, const HGChar* info);
#endif /* __HGCONSOLE_H__ */
\ No newline at end of file
......@@ -76,14 +76,16 @@ typedef HGUInt HGResult;
#define HGMIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define HGEXTERN_C extern "C"
#if defined(HG_CMP_MSC)
#define HGEXTERN_C extern "C"
#define HGAPI __stdcall
#else
#define HGEXTERN_C extern "C" __attribute ((visibility("default")))
#define HGAPI
#endif
#define HGAPIV __cdecl
#define HG_DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
typedef struct
......
......@@ -15,6 +15,14 @@
#if defined(HG_CMP_MSC)
#include <windows.h>
#else
#include <sys/time.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <iconv.h>
#endif
#endif /* __HGINC_H__ */
#ifndef __HGINFO_H__
#define __HGINFO_H__
#include "HGDef.h"
#include "HGBaseErr.h"
/* 致命错误 */
#define HGBASE_INFOTYPE_FATAL 1L
/* 一般错误 */
#define HGBASE_INFOTYPE_ERROR 2L
/* 警告 */
#define HGBASE_INFOTYPE_WARNING 4L
/* 一般描述信息 */
#define HGBASE_INFOTYPE_DESC 8L
/* 调试信息 */
#define HGBASE_INFOTYPE_DEBUG 16L
/* 写日志/控制台信息
* 参数:
* 1) type: in, 信息类型, 参见HGBASE_INFOTYPE_*
* 2) format: in, 信息格式
* 说明:
* 1) 信息的完整输出行: [日期-时间] [进程号/线程号] [信息类型] [信息]
* 2) 信息的实际输出行取决于HGGlobal.ini的配置
*/
HGEXTERN_C HGResult HGAPIV HGBase_WriteInfo(HGUInt type, const HGChar* format, ...);
#endif /* __HGINFO_H__ */
\ No newline at end of file
......@@ -8,39 +8,34 @@ HG_DECLARE_HANDLE(HGLog);
/* 开启日志
* 参数:
* 1) console: in, 是否将日志输出到控制台
* 2) fileName: in, 日志文件名
* 3) log: out, 日志句柄
* 1) fileName: in, 文件名
* 2) log: out, 日志句柄
* 说明:
* 1) 当只想将日志输出到控制台时, console传HGTRUE, fileName传NULL
* 2) 当只想将日志输出到文件时, console传HGFALSE, fileName传文件名
* 3) 写日志文件的方式是追加写,一条日志一行
*/
HGEXTERN_C HGResult HGAPI HGBase_CreateLog(HGBool console, const HGChar* fileName, HGLog* log);
HGEXTERN_C HGResult HGAPI HGBase_OpenLog(const HGChar* fileName, HGLog* log);
/* 关闭日志
* 参数:
* 1) log: in, 日志句柄
* 说明:
*/
HGEXTERN_C HGResult HGAPI HGBase_DestroyLog(HGLog log);
HGEXTERN_C HGResult HGAPI HGBase_CloseLog(HGLog log);
/* 获取日志文件大小
* 参数:
* 1) log: in, 日志句柄
* 2) size: out, 日志文件大小
* 说明:
* 1) 每次写入日志后,可以用该函数检查日志文件的大小,当日志文件足够大时,可以关闭该日志句柄,在新的日志文件上重新打开
* 1) 每次写入日志信息后,可以用该函数检查日志文件的大小,当日志文件足够大时,可以关闭该日志句柄,在新的日志文件上重新打开
*/
HGEXTERN_C HGResult HGAPI HGBase_GetLogFileSize(HGLog log, HGLonglong* size);
/* 写入日志
/* 写日志信息
* 参数:
* 1) log: in, 日志句柄
* 2) info: in, 单条日志信息, 长度不能超过1024字节
* 2) info: in, 信息, 一次一行, info无需加换行符
* 说明:
* 1) 写日志文件的方式是追加写,一条日志一行
* 2) 该函数不是线程安全的, 在不同进程或不同线程调用的时候, 需要加锁
* 1) 该函数不是线程安全的, 在不同进程或不同线程调用的时候, 需要加锁
*/
HGEXTERN_C HGResult HGAPI HGBase_WriteLog(HGLog log, const HGChar* info);
......
......@@ -42,4 +42,40 @@ HGEXTERN_C HGResult HGAPI HGBase_GetUuid(HGChar* uuid, HGUInt maxLen);
*/
HGEXTERN_C HGResult HGAPI HGBase_GetTmpFileName(HGChar* fileName, HGUInt maxLen);
/* 获取配置文件路径
*/
HGEXTERN_C HGResult HGAPI HGBase_GetConfigPath(HGChar* configPath, HGUInt maxLen);
/* 获取日志文件路径
*/
HGEXTERN_C HGResult HGAPI HGBase_GetLogFilePath(HGChar* logFilePath, HGUInt maxLen);
/* 获取进程名
*/
HGEXTERN_C HGResult HGAPI HGBase_GetProcessName(HGChar* name, HGUInt maxLen);
/* 通过文件全路径获取文件名
*/
HGEXTERN_C HGResult HGAPI HGBase_GetFileName(const HGChar *filePath, HGChar* name, HGUInt maxLen);
/* 设置ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_SetProfileInt(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, HGInt value);
/* 设置ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_SetProfileString(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, const HGChar *value);
/* 获取ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_GetProfileInt(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, HGInt def, HGInt* value);
/* 获取ini文件的值
*/
HGEXTERN_C HGResult HGAPI HGBase_GetProfileString(const HGChar* fileName, const HGChar* appName,
const HGChar* keyName, const HGChar* def, HGChar* value, HGUInt maxLen);
#endif /* __HGUTILITY_H__ */
\ No newline at end of file
......@@ -10,11 +10,23 @@ HG_DECLARE_HANDLE(HGTwainDSM);
HG_DECLARE_HANDLE(HGTwainDS);
/* 未知事件, 可能是该库未进行处理的事件 */
#define HGTWAIN_EVENT_UNKNOWN 0L
#define HGTWAIN_DSEVENT_UNKNOWN 0L
/* 图像准备好了 */
#define HGTWAIN_EVENT_XFERREADY 1L
#define HGTWAIN_DSEVENT_XFERREADY 1L
/* 用户点击了窗口上的关闭按钮 */
#define HGTWAIN_EVENT_CLOSEDSREQ 2L
#define HGTWAIN_DSEVENT_CLOSEDSREQ 2L
/* twain事件回调
* 参数:
* 1) dsm: in, DSM句柄
* 2) ds: in, DM句柄
* 3) event: in, 事件, 参见HGTWAIN_DSEVENT_*
* 4) param: in, 回调参数
* 说明:
* 1) 如果event为HGTWAIN_EVENT_XFERREADY, TWAIN状态从5变为6
* 2) 如果event为HGTWAIN_EVENT_CLOSEDSREQ, 表示需要关闭该DS
*/
typedef void (HGAPI *HGTwain_DSEventCallback)(HGTwainDSM dsm, HGTwainDS ds, HGUInt event, HGPointer param);
/* 加载DSM
* 参数:
......@@ -35,12 +47,11 @@ HGEXTERN_C HGResult HGAPI HGTwain_UnloadDSM(HGTwainDSM dsm);
/* 打开DSM
* 参数:
* 1) dsm: in, DSM句柄
* 2) hwnd: 应用层窗口句柄
* 说明:
* 1) 执行此函数后,TWAIN状态从2变为3
* 2) hwnd所在的线程需要有消息循环, 在消息循环中不断地调用HGTwain_GetEvent检查事件
* 2) 调用该函数的线程需要有消息循环
*/
HGEXTERN_C HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm, HWND hwnd);
HGEXTERN_C HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm);
/* 关闭DSM
* 参数:
......@@ -136,10 +147,14 @@ HGEXTERN_C HGResult HGAPI HGTwain_GetCapability(HGTwainDSM dsm, HGTwainDS ds, HG
* 1) dsm: in, DSM句柄
* 2) ds: in, DS句柄
* 3) showUI: in, 是否显示UI
* 4) parent: in, 父窗口句柄
* 5) func: in, 回调函数
* 6) param: in, 回调参数
* 说明:
* 1) 执行此函数后,TWAIN状态从4变为5
*/
HGEXTERN_C HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI);
HGEXTERN_C HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI, HWND parent,
HGTwain_DSEventCallback func, HGPointer param);
/* 停止DS
* 参数:
......@@ -150,19 +165,6 @@ HGEXTERN_C HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool
*/
HGEXTERN_C HGResult HGAPI HGTwain_DisableDS(HGTwainDSM dsm, HGTwainDS ds);
/* 获取DS事件
* 参数:
* 1) dsm: in, DSM句柄
* 2) ds: in, DS句柄
* 3) msg: in, hwnd的窗口消息
* 4) event: out, DS事件, 见HGTWAIN_EVENT_*
* 说明:
* 1) 执行此函数后,如果event为HGTWAIN_EVENT_XFERREADY, TWAIN状态从5变为6
* 2) 执行此函数后,如果event为HGTWAIN_EVENT_CLOSEDSREQ, 表示需要关闭该DS
* 3) 该函数需要在消息循环里面调用
*/
HGEXTERN_C HGResult HGAPI HGTwain_GetEvent(HGTwainDSM dsm, HGTwainDS ds, const MSG *msg, HGUInt *event);
/* 本地传输图像
* 参数:
* 1) dsm: in, DSM句柄
......@@ -171,8 +173,9 @@ HGEXTERN_C HGResult HGAPI HGTwain_GetEvent(HGTwainDSM dsm, HGTwainDS ds, const M
* 4) origin: in, 图像数据排列方式
* 5) image: out, 获取的图像
* 说明:
* 1) 执行此函数时,TWAIN状态从6变为7
* 2) 生成的image需要调用HGBase_DestroyImage销毁
* 1) 该函数需要在状态6调用
* 2) 执行此函数时,TWAIN状态从6变为7
* 3) 生成的image需要调用HGBase_DestroyImage销毁
*/
HGEXTERN_C HGResult HGAPI HGTwain_ImageNativeXfer(HGTwainDSM dsm, HGTwainDS ds, HGUInt type, HGUInt origin, HGImage *image);
......
......@@ -38,7 +38,7 @@ HGResult HGAPI HGTwain_UnloadDSM(HGTwainDSM dsm)
return HGBASE_ERR_OK;
}
HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm, HWND hwnd)
HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm)
{
if (NULL == dsm)
{
......@@ -46,7 +46,7 @@ HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm, HWND hwnd)
}
HGTwainImpl* twainImpl = (HGTwainImpl*)dsm;
return twainImpl->OpenDSM(hwnd);
return twainImpl->OpenDSM();
}
HGResult HGAPI HGTwain_CloseDSM(HGTwainDSM dsm)
......@@ -148,7 +148,8 @@ HGResult HGAPI HGTwain_GetCapability(HGTwainDSM dsm, HGTwainDS ds, HGUInt cap, H
return twainImpl->GetCapability(ds, cap, value);
}
HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI)
HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI, HWND parent,
HGTwain_DSEventCallback func, HGPointer param)
{
if (NULL == dsm)
{
......@@ -156,7 +157,7 @@ HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI)
}
HGTwainImpl* twainImpl = (HGTwainImpl*)dsm;
return twainImpl->EnableDS(ds, showUI);
return twainImpl->EnableDS(ds, showUI, parent, func, param);
}
HGResult HGAPI HGTwain_DisableDS(HGTwainDSM dsm, HGTwainDS ds)
......@@ -170,17 +171,6 @@ HGResult HGAPI HGTwain_DisableDS(HGTwainDSM dsm, HGTwainDS ds)
return twainImpl->DisableDS(ds);
}
HGResult HGAPI HGTwain_GetEvent(HGTwainDSM dsm, HGTwainDS ds, const MSG* msg, HGUInt* event)
{
if (NULL == dsm)
{
return HGBASE_ERR_INVALIDARG;
}
HGTwainImpl* twainImpl = (HGTwainImpl*)dsm;
return twainImpl->GetEvent(ds, msg, event);
}
HGResult HGAPI HGTwain_ImageNativeXfer(HGTwainDSM dsm, HGTwainDS ds, HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == dsm)
......
......@@ -10,11 +10,23 @@ HG_DECLARE_HANDLE(HGTwainDSM);
HG_DECLARE_HANDLE(HGTwainDS);
/* 未知事件, 可能是该库未进行处理的事件 */
#define HGTWAIN_EVENT_UNKNOWN 0L
#define HGTWAIN_DSEVENT_UNKNOWN 0L
/* 图像准备好了 */
#define HGTWAIN_EVENT_XFERREADY 1L
#define HGTWAIN_DSEVENT_XFERREADY 1L
/* 用户点击了窗口上的关闭按钮 */
#define HGTWAIN_EVENT_CLOSEDSREQ 2L
#define HGTWAIN_DSEVENT_CLOSEDSREQ 2L
/* twain事件回调
* 参数:
* 1) dsm: in, DSM句柄
* 2) ds: in, DM句柄
* 3) event: in, 事件, 参见HGTWAIN_DSEVENT_*
* 4) param: in, 回调参数
* 说明:
* 1) 如果event为HGTWAIN_EVENT_XFERREADY, TWAIN状态从5变为6
* 2) 如果event为HGTWAIN_EVENT_CLOSEDSREQ, 表示需要关闭该DS
*/
typedef void (HGAPI *HGTwain_DSEventCallback)(HGTwainDSM dsm, HGTwainDS ds, HGUInt event, HGPointer param);
/* 加载DSM
* 参数:
......@@ -35,12 +47,11 @@ HGEXTERN_C HGResult HGAPI HGTwain_UnloadDSM(HGTwainDSM dsm);
/* 打开DSM
* 参数:
* 1) dsm: in, DSM句柄
* 2) hwnd: 应用层窗口句柄
* 说明:
* 1) 执行此函数后,TWAIN状态从2变为3
* 2) hwnd所在的线程需要有消息循环, 在消息循环中不断地调用HGTwain_GetEvent检查事件
* 2) 调用该函数的线程需要有消息循环
*/
HGEXTERN_C HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm, HWND hwnd);
HGEXTERN_C HGResult HGAPI HGTwain_OpenDSM(HGTwainDSM dsm);
/* 关闭DSM
* 参数:
......@@ -136,10 +147,14 @@ HGEXTERN_C HGResult HGAPI HGTwain_GetCapability(HGTwainDSM dsm, HGTwainDS ds, HG
* 1) dsm: in, DSM句柄
* 2) ds: in, DS句柄
* 3) showUI: in, 是否显示UI
* 4) parent: in, 父窗口句柄
* 5) func: in, 回调函数
* 6) param: in, 回调参数
* 说明:
* 1) 执行此函数后,TWAIN状态从4变为5
*/
HGEXTERN_C HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI);
HGEXTERN_C HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool showUI, HWND parent,
HGTwain_DSEventCallback func, HGPointer param);
/* 停止DS
* 参数:
......@@ -150,19 +165,6 @@ HGEXTERN_C HGResult HGAPI HGTwain_EnableDS(HGTwainDSM dsm, HGTwainDS ds, HGBool
*/
HGEXTERN_C HGResult HGAPI HGTwain_DisableDS(HGTwainDSM dsm, HGTwainDS ds);
/* 获取DS事件
* 参数:
* 1) dsm: in, DSM句柄
* 2) ds: in, DS句柄
* 3) msg: in, hwnd的窗口消息
* 4) event: out, DS事件, 见HGTWAIN_EVENT_*
* 说明:
* 1) 执行此函数后,如果event为HGTWAIN_EVENT_XFERREADY, TWAIN状态从5变为6
* 2) 执行此函数后,如果event为HGTWAIN_EVENT_CLOSEDSREQ, 表示需要关闭该DS
* 3) 该函数需要在消息循环里面调用
*/
HGEXTERN_C HGResult HGAPI HGTwain_GetEvent(HGTwainDSM dsm, HGTwainDS ds, const MSG *msg, HGUInt *event);
/* 本地传输图像
* 参数:
* 1) dsm: in, DSM句柄
......@@ -171,8 +173,9 @@ HGEXTERN_C HGResult HGAPI HGTwain_GetEvent(HGTwainDSM dsm, HGTwainDS ds, const M
* 4) origin: in, 图像数据排列方式
* 5) image: out, 获取的图像
* 说明:
* 1) 执行此函数时,TWAIN状态从6变为7
* 2) 生成的image需要调用HGBase_DestroyImage销毁
* 1) 该函数需要在状态6调用
* 2) 执行此函数时,TWAIN状态从6变为7
* 3) 生成的image需要调用HGBase_DestroyImage销毁
*/
HGEXTERN_C HGResult HGAPI HGTwain_ImageNativeXfer(HGTwainDSM dsm, HGTwainDS ds, HGUInt type, HGUInt origin, HGImage *image);
......
#include "HGTwainImpl.hpp"
#include "../base/HGInc.h"
extern HMODULE g_hInst;
ULONG HGTwainImpl::m_nRefCount = 0;
HGTwainImpl::HGTwainImpl()
{
m_hDll = NULL;
m_pDSMProc = NULL;
GetIdentity();
m_hMessageWnd = NULL;
m_hWnd = 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;
}
HGTwainImpl::~HGTwainImpl()
{
--m_nRefCount;
if (0 == m_nRefCount)
{
UnregisterClassW(L"TwainDSMWnd", g_hInst);
}
}
HGResult HGTwainImpl::LoadDSM()
......@@ -56,20 +82,26 @@ HGResult HGTwainImpl::UnloadDSM()
return HGBASE_ERR_OK;
}
HGResult HGTwainImpl::OpenDSM(HWND hwnd)
HGResult HGTwainImpl::OpenDSM()
{
if (NULL == m_pDSMProc || m_DSMOpen)
{
return HGBASE_ERR_FAIL;
}
USHORT ret = m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF)&hwnd);
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);
if (TWRC_SUCCESS != ret)
{
DestroyWindow(hWnd);
return HGBASE_ERR_FAIL;
}
m_hMessageWnd = hwnd;
m_hWnd = hWnd;
m_DSMOpen = HGTRUE;
// 获取DS列表
......@@ -79,18 +111,12 @@ HGResult HGTwainImpl::OpenDSM(HWND hwnd)
{
HGTwainDSImpl dsImpl;
memcpy(&dsImpl.ds, &ds, sizeof(TW_IDENTITY));
dsImpl.open = HGFALSE;
dsImpl.showUI = HGFALSE;
dsImpl.enable = HGFALSE;
m_DSList.push_back(dsImpl);
while (TWRC_SUCCESS == m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &ds))
{
HGTwainDSImpl dsImpl;
memcpy(&dsImpl.ds, &ds, sizeof(TW_IDENTITY));
dsImpl.open = HGFALSE;
dsImpl.showUI = HGFALSE;
dsImpl.enable = HGFALSE;
m_DSList.push_back(dsImpl);
}
}
......@@ -114,8 +140,9 @@ HGResult HGTwainImpl::CloseDSM()
// 清理DS列表
m_DSList.clear();
m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&m_hMessageWnd);
m_hMessageWnd = NULL;
m_pDSMProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&m_hWnd);
DestroyWindow(m_hWnd);
m_hWnd = NULL;
m_DSMOpen = HGFALSE;
return HGBASE_ERR_OK;
}
......@@ -340,6 +367,7 @@ HGResult HGTwainImpl::GetCapability(HGTwainDS ds, HGUInt cap, HGUInt* value)
}
// 获取参数
*value = 0;
return HGBASE_ERR_OK;
}
......@@ -349,9 +377,9 @@ HGResult HGTwainImpl::GetCapability(HGTwainDS ds, HGUInt cap, HGUInt* value)
}
HGResult HGTwainImpl::EnableDS(HGTwainDS ds, HGBool showUI)
HGResult HGTwainImpl::EnableDS(HGTwainDS ds, HGBool showUI, HWND parent, HGTwain_DSEventCallback func, HGPointer param)
{
if (NULL == ds)
if (NULL == ds || NULL == func)
{
return HGBASE_ERR_INVALIDARG;
}
......@@ -367,7 +395,7 @@ HGResult HGTwainImpl::EnableDS(HGTwainDS ds, HGBool showUI)
TW_USERINTERFACE twUI;
twUI.ShowUI = (TW_BOOL)showUI;
twUI.hParent = (TW_HANDLE)m_hMessageWnd;
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)
{
......@@ -375,6 +403,9 @@ HGResult HGTwainImpl::EnableDS(HGTwainDS ds, HGBool showUI)
}
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;
}
......@@ -401,10 +432,13 @@ HGResult HGTwainImpl::DisableDS(HGTwainDS ds)
TW_USERINTERFACE twUI;
twUI.ShowUI = (TW_BOOL)m_DSList[i].showUI;
twUI.hParent = (TW_HANDLE)m_hMessageWnd;
twUI.hParent = (TW_HANDLE)m_DSList[i].param;
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;
}
......@@ -413,43 +447,6 @@ HGResult HGTwainImpl::DisableDS(HGTwainDS ds)
return HGBASE_ERR_FAIL;
}
HGResult HGTwainImpl::GetEvent(HGTwainDS ds, const MSG* msg, HGUInt* event)
{
if (NULL == ds || NULL == msg || NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
for (int i = 0; i < (int)m_DSList.size(); ++i)
{
if (ds == (HGTwainDS)&m_DSList[i])
{
if (!m_DSList[i].enable)
{
return HGBASE_ERR_FAIL;
}
TW_EVENT twEvent;
twEvent.pEvent = (TW_MEMREF)msg;
twEvent.TWMessage = MSG_NULL;
USHORT ret = m_pDSMProc(&m_AppId, &m_DSList[i].ds, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF)&twEvent);
if (TWRC_DSEVENT != ret)
{
return HGBASE_ERR_FAIL;
}
*event = HGTWAIN_EVENT_UNKNOWN;
if (MSG_XFERREADY == twEvent.TWMessage)
*event = HGTWAIN_EVENT_XFERREADY;
else if (MSG_CLOSEDSREQ == twEvent.TWMessage)
*event = HGTWAIN_EVENT_CLOSEDSREQ;
return HGBASE_ERR_OK;
}
}
return HGBASE_ERR_FAIL;
}
HGResult HGTwainImpl::ImageNativeXfer(HGTwainDS ds, HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == ds || NULL == image)
......@@ -564,3 +561,39 @@ void HGTwainImpl::GetIdentity()
strcpy(m_AppId.ProductFamily, "Generic");
strcpy(m_AppId.ProductName, "MyTwain");
}
LRESULT CALLBACK HGTwainImpl::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HGTwainImpl *p = (HGTwainImpl *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
if (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)
{
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 && 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;
p->m_DSList[i].func((HGTwainDSM)p, (HGTwainDS)&p->m_DSList[i], event, p->m_DSList[i].param);
}
}
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
\ No newline at end of file
......@@ -13,12 +13,18 @@ struct HGTwainDSImpl
memset(&ds, 0, sizeof(TW_IDENTITY));
open = HGFALSE;
showUI = HGFALSE;
parent = NULL;
func = NULL;
param = NULL;
enable = HGFALSE;
}
TW_IDENTITY ds;
HGBool open;
HGBool showUI;
HWND parent;
HGTwain_DSEventCallback func;
HGPointer param;
HGBool enable;
};
......@@ -30,7 +36,7 @@ public:
HGResult LoadDSM();
HGResult UnloadDSM();
HGResult OpenDSM(HWND hwnd);
HGResult OpenDSM();
HGResult CloseDSM();
HGResult GetDSList(HGTwainDS* ds, HGUInt* size);
......@@ -42,21 +48,22 @@ public:
HGResult SetCapability(HGTwainDS ds, HGUInt cap, HGInt value);
HGResult GetCapability(HGTwainDS ds, HGUInt cap, HGUInt* value);
HGResult EnableDS(HGTwainDS ds, HGBool showUI);
HGResult EnableDS(HGTwainDS ds, HGBool showUI, HWND parent, HGTwain_DSEventCallback func, HGPointer param);
HGResult DisableDS(HGTwainDS ds);
HGResult GetEvent(HGTwainDS ds, const MSG* msg, HGUInt* event);
HGResult ImageNativeXfer(HGTwainDS ds, HGUInt type, HGUInt origin, HGImage* image);
HGResult EndXfer(HGTwainDS ds, HGUInt* count);
HGResult Reset(HGTwainDS ds);
private:
void GetIdentity();
static LRESULT CALLBACK WndProc(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_hMessageWnd;
HWND m_hWnd;
HGBool m_DSMOpen;
std::vector<HGTwainDSImpl> m_DSList;
};
......
#include <windows.h>
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;
}
return TRUE;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment