📄 tmisc.cpp
字号:
static char *tmisc_id =
"@(#)Copyright (C) H.Shirouzu 1996-2005 tmisc.cpp Ver1.00";
/* ========================================================================
Project Name : Win32 Lightweight Class Library Test
Module Name : Application Frame Class
Create : 1996-06-01(Sat)
Update : 2005-11-28(Mon)
Copyright : H.Shirouzu
Reference :
======================================================================== */
#include "tlib.h"
#include <stdio.h>
#include <mbstring.h>
#include <stdlib.h>
struct TResHashObj {
TResHashObj *prior;
TResHashObj *next;
UINT resId;
void *val;
TResHashObj(UINT _resId, void *_val=NULL) { prior = next = NULL; resId = _resId; val = _val; }
};
class TResHash {
protected:
int hashNum;
TResHashObj **hashTbl;
public:
TResHash(int _hashNum);
BOOL Register(TResHashObj *);
TResHashObj *Search(UINT id);
};
TResHash::TResHash(int _hashNum)
{
hashNum = _hashNum;
hashTbl = new TResHashObj *[hashNum];
memset(hashTbl, 0, sizeof(TResHashObj *) * hashNum);
}
BOOL TResHash::Register(TResHashObj *target)
{
TResHashObj **obj;
for (obj = &hashTbl[target->resId % hashNum]; *obj; obj=&(*obj)->next)
;
*obj = target;
return TRUE;
}
TResHashObj *TResHash::Search(UINT resId)
{
for (TResHashObj *obj = hashTbl[resId % hashNum]; obj; obj=obj->next) {
if (obj->resId == resId)
return obj;
}
return NULL;
}
static HINSTANCE defaultInstance;
void InitInstanceForLoadStr(HINSTANCE hI)
{
defaultInstance = hI;
}
LPSTR GetLoadStrA(UINT resId, HINSTANCE hI)
{
static TResHash *hash;
if (hash == NULL) {
hash = new TResHash(100);
}
char buf[1024];
TResHashObj *obj;
if ((obj = hash->Search(resId)) == NULL) {
if (::LoadStringA(hI ? hI : defaultInstance, resId, buf, sizeof(buf)) >= 0) {
obj = new TResHashObj(resId, strdup(buf));
hash->Register(obj);
}
}
return obj ? (char *)obj->val : NULL;
}
LPWSTR GetLoadStrW(UINT resId, HINSTANCE hI)
{
static TResHash *hash;
if (hash == NULL) {
hash = new TResHash(100);
}
WCHAR buf[1024];
TResHashObj *obj;
if ((obj = hash->Search(resId)) == NULL) {
if (::LoadStringW(hI ? hI : defaultInstance, resId, buf, sizeof(buf) / sizeof(WCHAR)) >= 0) {
obj = new TResHashObj(resId, wcsdup(buf));
hash->Register(obj);
}
}
return obj ? (LPWSTR)obj->val : NULL;
}
static LCID defaultLCID;
void TSetDefaultLCID(LCID lcid)
{
defaultLCID = lcid ? lcid : ::GetSystemDefaultLCID();
::SetThreadLocale(defaultLCID);
}
HMODULE TLoadLibrary(LPTSTR dllname)
{
HMODULE hModule = ::LoadLibrary(dllname);
if (defaultLCID)
::SetThreadLocale(defaultLCID);
return hModule;
}
/*=========================================================================
僷僗崌惉乮ANSI 斉乯
=========================================================================*/
int MakePath(char *dest, const char *dir, const char *file)
{
BOOL separetor = TRUE;
int len;
if ((len = strlen(dir)) == 0)
return wsprintf(dest, "%s", file);
if (dir[len -1] == '\\') // 昞側偳丄2byte栚偑'\\'偱廔傞暥帤楍懳嶔
{
if (len >= 2 && IsDBCSLeadByte(dir[len -2]) == FALSE)
separetor = FALSE;
else {
for (u_char *p=(u_char *)dir; *p && p[1]; IsDBCSLeadByte(*p) ? p+=2 : p++)
;
if (*p == '\\')
separetor = FALSE;
}
}
return wsprintf(dest, "%s%s%s", dir, separetor ? "\\" : "", file);
}
/*=========================================================================
僷僗崌惉乮UNICODE 斉乯
=========================================================================*/
int MakePathW(WCHAR *dest, const WCHAR *dir, const WCHAR *file)
{
int len;
if ((len = wcslen(dir)) == 0)
return wsprintfW(dest, L"%s", file);
return wsprintfW(dest, L"%s%s%s", dir, dir[len -1] == L'\\' ? L"" : L"\\" , file);
}
WCHAR lGetCharIncW(const WCHAR **str)
{
return *(*str)++;
}
WCHAR lGetCharIncA(const char **str)
{
WCHAR ch = *(*str)++;
if (IsDBCSLeadByte((BYTE)ch)) {
ch <<= BITS_OF_BYTE;
ch |= *(*str)++; // null 敾掕偼庤敳偒
}
return ch;
}
WCHAR lGetCharW(const WCHAR *str, int offset)
{
return str[offset];
}
WCHAR lGetCharA(const char *str, int offset)
{
while (offset-- > 0)
lGetCharIncA(&str);
return lGetCharIncA(&str);
}
void lSetCharW(WCHAR *str, int offset, WCHAR ch)
{
str[offset] = ch;
}
void lSetCharA(char *str, int offset, WCHAR ch)
{
while (offset-- > 0) {
if (IsDBCSLeadByte(*str++))
*str++;
}
BYTE high_ch = ch >> BITS_OF_BYTE;
if (high_ch)
*str++ = high_ch;
*str = (BYTE)ch;
}
/*=========================================================================
Debug
=========================================================================*/
void Debug(char *fmt,...)
{
static char buf[8192];
va_list ap;
va_start(ap, fmt);
_vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
::OutputDebugString(buf);
}
/*=========================================================================
椺奜忣曬庢摼
=========================================================================*/
static char *ExceptionTitle;
static char *ExceptionLogFile;
static char *ExceptionLogInfo;
#define STACKDUMP_SIZE 256
#define MAX_STACKDUMP_SIZE 8192
LONG WINAPI Local_UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *info)
{
static char buf[(STACKDUMP_SIZE/sizeof(DWORD)) * 10 + 100]; // 10 ... %08x + \r\n
static HANDLE hFile;
static SYSTEMTIME tm;
static CONTEXT *context;
static DWORD len, i, j;
static char *stack;
hFile = ::CreateFile(ExceptionLogFile, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
::SetFilePointer(hFile, 0, 0, FILE_END);
::GetLocalTime(&tm);
context = info->ContextRecord;
len = sprintf(buf,
"------ %s -----\r\n"
" Date : %d/%02d/%02d %02d:%02d:%02d\r\n"
" Code/Addr : %X / %p\r\n"
" AX/BX/CX/DX : %08x / %08x / %08x / %08x\r\n"
" SI/DI/BP/SP : %08x / %08x / %08x / %08x\r\n"
"------- stack info -----\r\n"
, ExceptionTitle
, tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond
, info->ExceptionRecord->ExceptionCode, info->ExceptionRecord->ExceptionAddress
, context->Eax, context->Ebx, context->Ecx, context->Edx
, context->Esi, context->Edi, context->Ebp, context->Esp
);
::WriteFile(hFile, buf, len, &len, 0);
for (i=0; i < MAX_STACKDUMP_SIZE / STACKDUMP_SIZE; i++) {
stack = (char *)context->Esp + (i * STACKDUMP_SIZE);
if (::IsBadReadPtr(stack, STACKDUMP_SIZE))
break;
len = 0;
for (j=0; j < STACKDUMP_SIZE / sizeof(DWORD); j++)
len += sprintf(buf + len, "%08x%s", ((DWORD *)stack)[j], ((j+1)%8) ? " " : "\r\n");
::WriteFile(hFile, buf, len, &len, 0);
}
len = sprintf(buf, "------------------------\r\n\r\n");
::WriteFile(hFile, buf, len, &len, 0);
::CloseHandle(hFile);
sprintf(buf, ExceptionLogInfo, ExceptionLogFile);
::MessageBox(0, buf, ExceptionTitle, MB_OK);
return EXCEPTION_EXECUTE_HANDLER;
}
BOOL InstallExceptionFilter(char *title, char *info)
{
char buf[MAX_PATH];
::GetModuleFileName(NULL, buf, sizeof(buf));
strcpy(strrchr(buf, '.'), "_exception.log");
ExceptionLogFile = strdup(buf);
ExceptionTitle = strdup(title);
ExceptionLogInfo = info;
::SetUnhandledExceptionFilter(&Local_UnhandledExceptionFilter);
return TRUE;
}
/*=========================================================================
UCS2(W) - UTF-8(U8) - ANSI(A) 憡屳曄姺
=========================================================================*/
WCHAR *AtoW(const char *src, BOOL noStatic) {
static WCHAR *_wbuf = NULL;
WCHAR *wtmp = NULL;
WCHAR *&wbuf = noStatic ? wtmp : _wbuf;
if (wbuf) {
delete [] wbuf;
wbuf = NULL;
}
int len;
if ((len = AtoW(src, NULL, 0)) > 0) {
wbuf = new WCHAR [len];
AtoW(src, wbuf, len);
}
return wbuf;
}
WCHAR *U8toW(const char *src, BOOL noStatic) {
static WCHAR *_wbuf = NULL;
WCHAR *wtmp = NULL;
WCHAR *&wbuf = noStatic ? wtmp : _wbuf;
if (wbuf) {
delete [] wbuf;
wbuf = NULL;
}
int len;
if ((len = U8toW(src, NULL, 0)) > 0) {
wbuf = new WCHAR [len];
U8toW(src, wbuf, len);
}
return wbuf;
}
char *WtoU8(const WCHAR *src, BOOL noStatic) {
static char *_buf = NULL;
char *tmp = NULL;
char *&buf = noStatic ? tmp : _buf;
if (buf) {
delete [] buf;
buf = NULL;
}
int len;
if ((len = WtoU8(src, NULL, 0)) > 0) {
buf = new char [len];
WtoU8(src, buf, len);
}
return buf;
}
char *WtoA(const WCHAR *src, BOOL noStatic) {
static char *_buf = NULL;
char *tmp = NULL;
char *&buf = noStatic ? tmp : _buf;
if (buf) {
delete [] buf;
buf = NULL;
}
int len;
if ((len = WtoA(src, NULL, 0)) > 0) {
buf = new char [len];
WtoA(src, buf, len);
}
return buf;
}
char *AtoU8(const char *src, BOOL noStatic) {
static char *_buf = NULL;
char *tmp = NULL;
char *&buf = noStatic ? tmp : _buf;
if (buf) {
delete [] buf;
buf = NULL;
}
WCHAR *wsrc = AtoW(src, TRUE);
if (wsrc) {
buf = WtoU8(wsrc, TRUE);
}
delete [] wsrc;
return buf;
}
char *U8toA(const char *src, BOOL noStatic) {
static char *_buf = NULL;
char *tmp = NULL;
char *&buf = noStatic ? tmp : _buf;
if (buf) {
delete [] buf;
buf = NULL;
}
WCHAR *wsrc = U8toW(src, TRUE);
if (wsrc) {
buf = WtoA(wsrc, TRUE);
}
delete [] wsrc;
return buf;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -