📄 platform_win32.c
字号:
tchar_t s[1024];
vstprintf( s, Msg, (VA_LIST)(&Msg+1) );
if (Wait) WaitEnd();
MessageBox(NULL,s,Title,MB_OK|MB_SETFOREGROUND);
if (Wait) WaitBegin();
}
void DebugTime(const tchar_t* Name)
{
SYSTEMTIME t;
GetSystemTime(&t);
DebugMessage(T("%02d:%02d:%02d.%03d %s"),t.wHour,t.wMinute,t.wSecond,t.wMilliseconds,Name);
}
void DebugMessage(const tchar_t* Msg,...)
{
tchar_t s[1024];
#ifndef NDEBUG
if (!Debug)
Debug = StreamOpen(T("\\debug.txt"),1);
#else
if (!Debug)
{
stprintf(s,T("%s\\log.txt"),DocPath);
Debug = StreamOpen(s,1);
}
#endif
s[0]=0;
#ifndef NDEBUG
// stprintf(s,T("%04x "),(int)GetCurrentThreadId());
#endif
vstprintf( s+tcslen(s), Msg, (VA_LIST)(&Msg+1) );
tcscat(s,T("\n"));
#ifndef NDEBUG
OutputDebugString(s);
#endif
StreamPrintf(Debug,T("%s"),s);
}
typedef struct contextreg
{
int Ofs;
const tchar_t* Name;
} contextreg;
#if defined( _M_IX86 )
static contextreg Reg[] =
{
OFS(CONTEXT,Eax), T("eax"),
OFS(CONTEXT,Ebx), T("ebx"),
OFS(CONTEXT,Ecx), T("ecx"),
OFS(CONTEXT,Edx), T("edx"),
OFS(CONTEXT,Esi), T("esi"),
OFS(CONTEXT,Edi), T("edi"),
OFS(CONTEXT,Ebp), T("ebp"),
OFS(CONTEXT,Esp), T("esp"),
OFS(CONTEXT,Eip), T("eip"),
OFS(CONTEXT,EFlags), T("flags"),
OFS(CONTEXT,Esp), NULL,
};
#elif defined( MIPS )
static contextreg Reg[] =
{
OFS(CONTEXT,IntZero), T("Zero"),
OFS(CONTEXT,IntAt), T("At"),
OFS(CONTEXT,IntV0), T("V0"),
OFS(CONTEXT,IntV1), T("V1"),
OFS(CONTEXT,IntA0), T("A0"),
OFS(CONTEXT,IntA1), T("A1"),
OFS(CONTEXT,IntA2), T("A2"),
OFS(CONTEXT,IntA3), T("A3"),
OFS(CONTEXT,IntT0), T("T0"),
OFS(CONTEXT,IntT1), T("T1"),
OFS(CONTEXT,IntT2), T("T2"),
OFS(CONTEXT,IntT3), T("T3"),
OFS(CONTEXT,IntT4), T("T4"),
OFS(CONTEXT,IntT5), T("T5"),
OFS(CONTEXT,IntT6), T("T6"),
OFS(CONTEXT,IntT7), T("T7"),
OFS(CONTEXT,IntS0), T("S0"),
OFS(CONTEXT,IntS1), T("S1"),
OFS(CONTEXT,IntS2), T("S2"),
OFS(CONTEXT,IntS3), T("S3"),
OFS(CONTEXT,IntS4), T("S4"),
OFS(CONTEXT,IntS5), T("S5"),
OFS(CONTEXT,IntS6), T("S6"),
OFS(CONTEXT,IntS7), T("S7"),
OFS(CONTEXT,IntT8), T("T8"),
OFS(CONTEXT,IntT9), T("T9"),
OFS(CONTEXT,IntK0), T("K0"),
OFS(CONTEXT,IntK1), T("K1"),
OFS(CONTEXT,IntGp), T("Gp"),
OFS(CONTEXT,IntSp), T("Sp"),
OFS(CONTEXT,IntS8), T("S8"),
OFS(CONTEXT,IntRa), T("Ra"),
OFS(CONTEXT,IntLo), T("Lo"),
OFS(CONTEXT,IntHi), T("Hi"),
OFS(CONTEXT,IntSp), NULL,
};
#elif defined( ARM )
static contextreg Reg[] =
{
OFS(CONTEXT,R0), T("R0"),
OFS(CONTEXT,R1), T("R1"),
OFS(CONTEXT,R2), T("R2"),
OFS(CONTEXT,R3), T("R3"),
OFS(CONTEXT,R4), T("R4"),
OFS(CONTEXT,R5), T("R5"),
OFS(CONTEXT,R6), T("R6"),
OFS(CONTEXT,R7), T("R7"),
OFS(CONTEXT,R8), T("R8"),
OFS(CONTEXT,R9), T("R9"),
OFS(CONTEXT,R10),T("R10"),
OFS(CONTEXT,R11),T("R11"),
OFS(CONTEXT,R12),T("R12"),
OFS(CONTEXT,Sp), T("Sp"),
OFS(CONTEXT,Lr), T("Lr"),
OFS(CONTEXT,Pc), T("Pc"),
OFS(CONTEXT,Psr),T("Psr"),
OFS(CONTEXT,Sp), NULL,
};
#elif defined( SH3 )
static contextreg Reg[] =
{
OFS(CONTEXT,PR), T("PR"),
OFS(CONTEXT,MACH), T("MACH"),
OFS(CONTEXT,MACL), T("MACL"),
OFS(CONTEXT,GBR), T("GBR"),
OFS(CONTEXT,R0), T("R0"),
OFS(CONTEXT,R1), T("R1"),
OFS(CONTEXT,R2), T("R2"),
OFS(CONTEXT,R3), T("R3"),
OFS(CONTEXT,R4), T("R4"),
OFS(CONTEXT,R5), T("R5"),
OFS(CONTEXT,R6), T("R6"),
OFS(CONTEXT,R7), T("R7"),
OFS(CONTEXT,R8), T("R8"),
OFS(CONTEXT,R9), T("R9"),
OFS(CONTEXT,R10), T("R10"),
OFS(CONTEXT,R11), T("R11"),
OFS(CONTEXT,R12), T("R12"),
OFS(CONTEXT,R13), T("R13"),
OFS(CONTEXT,R14), T("R14"),
OFS(CONTEXT,R15), T("R15"),
OFS(CONTEXT,R15), NULL,
};
#else
static contextreg Reg[] = { -1, NULL };
#endif
void Dump()
{
stream* File;
tchar_t Path[MAXPATH];
stprintf(Path,T("%s\\dump.txt"),DocPath);
File = StreamOpen(Path,1);
if (File)
{
NodeDump(File);
StreamClose(File);
MessageBox(NULL,String(PLATFORM_ID,PLATFORM_DUMP_MESSAGE),
String(PLATFORM_ID,PLATFORM_DUMP_TITLE),MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
}
}
int SafeException(void* p)
{
EXCEPTION_POINTERS* Data = (EXCEPTION_POINTERS*)p;
stream* File;
tchar_t Path[MAXPATH];
stprintf(Path,T("%s\\crash.txt"),DocPath);
File = StreamOpen(Path,1);
if (File)
{
void** Stack;
contextreg* r;
int No;
const uint8_t* Context = (const uint8_t*) Data->ContextRecord;
EXCEPTION_RECORD* Record = Data->ExceptionRecord;
tchar_t* Name;
int DllBase;
tchar_t DllName[MAXPATH];
StreamPrintf(File,T("%s %s crash report\n----------------------------\n"),NodeProgramId(),NodeVersion());
switch (Record->ExceptionCode)
{
case STATUS_ACCESS_VIOLATION: Name = T("Access violation"); break;
case STATUS_BREAKPOINT: Name = T("Breakpoint"); break;
case STATUS_DATATYPE_MISALIGNMENT: Name = T("Datatype misalignment"); break;
case STATUS_ILLEGAL_INSTRUCTION: Name = T("Illegal instruction"); break;
case STATUS_INTEGER_DIVIDE_BY_ZERO: Name = T("Int divide by zero"); break;
case STATUS_INTEGER_OVERFLOW: Name = T("Int overflow"); break;
case STATUS_PRIVILEGED_INSTRUCTION: Name = T("Priv instruction"); break;
case STATUS_STACK_OVERFLOW: Name = T("Stack overflow"); break;
default: Name = T("Unknown"); break;
}
NodeLocate(Record->ExceptionAddress,DllName,&DllBase);
StreamPrintf(File,T("%s(%08x) at %08x (%s:%08x)"),Name,Record->ExceptionCode,Record->ExceptionAddress,DllName,DllBase);
if (Record->ExceptionCode == STATUS_ACCESS_VIOLATION)
{
if (Record->ExceptionInformation[0])
Name = T("Write to");
else
Name = T("Read from");
StreamPrintf(File,T("\n%s %08x"),Name,Record->ExceptionInformation[1]);
if (NodeLocate((void*)Record->ExceptionInformation[1],DllName,&DllBase))
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
}
// context
StreamPrintf(File,T("\n\ncpu dump:"));
for (r=Reg;r->Name;++r)
{
void* Ptr = *(void**)(Context+r->Ofs);
StreamPrintf(File,T("\n%-5s = %08x"),r->Name,Ptr);
if (NodeLocate(Ptr,DllName,&DllBase))
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
}
if (r->Ofs >= 0)
{
StreamPrintf(File,T("\n\nstack dump:"));
Stack = *(void***)(Context+r->Ofs);
for (No=0;No<256;++No,++Stack)
{
if (!IsBadReadPtr(Stack,sizeof(void*)))
{
void* Ptr = *Stack;
StreamPrintf(File,T("\n%08x %08x"),Stack,Ptr);
if (NodeLocate(Ptr,DllName,&DllBase))
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
}
else
StreamPrintf(File,T("\n%08x ????????"),Stack);
}
}
StreamPrintf(File,T("\n\nnode dump:\n"));
NodeDump(File);
StreamClose(File);
}
MessageBox(NULL,String(PLATFORM_ID,PLATFORM_CRASH_MESSAGE),
String(PLATFORM_ID,PLATFORM_CRASH_TITLE),MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_ICONSTOP);
TerminateProcess(GetCurrentProcess(),1);
return 1;
}
void SetFileAssociation(const tchar_t* Ext,const tchar_t* Type,bool_t State)
{
DWORD Disp=0;
HKEY Key;
DWORD RegSize;
DWORD RegType;
tchar_t Base[64];
tchar_t Backup[256];
stprintf(Base,T(".%s"),Ext);
stprintf(Backup,T("%sBackup"),Type);
if (RegOpenKeyEx( HKEY_CLASSES_ROOT, Base, 0, ACCESS_SAVE, &Key ) == ERROR_SUCCESS)
{
RegSize=sizeof(Base);
if (RegQueryValueEx( Key, NULL, 0, &RegType, (LPBYTE)Base, &RegSize ) == ERROR_SUCCESS)
{
if (TcsICmp(Base,Type)!=0)
{
if (State)
{
RegSetValueEx( Key, NULL, 0, REG_SZ, (LPBYTE)Type, (tcslen(Type)+1)*sizeof(tchar_t) );
RegSetValueEx( Key, Backup, 0, REG_SZ, (LPBYTE)Base, RegSize );
}
}
else
if (!State)
{
RegSize = sizeof(Base);
if (RegQueryValueEx( Key, Backup, 0, &RegType, (LPBYTE)Base, &RegSize ) != ERROR_SUCCESS)
{
Base[0] = 0;
RegSize = sizeof(tchar_t);
}
RegSetValueEx( Key, NULL, 0, REG_SZ, (LPBYTE)Base, RegSize);
}
}
RegCloseKey( Key );
}
else
if (State)
{
if (RegCreateKeyEx( HKEY_CLASSES_ROOT, Base, 0, NULL, 0, ACCESS_SAVE, NULL, &Key, &Disp ) == ERROR_SUCCESS)
{
RegSetValueEx( Key, NULL, 0, REG_SZ, (LPBYTE)Type, (tcslen(Type)+1)*sizeof(tchar_t) );
RegCloseKey( Key );
}
}
}
bool_t GetFileAssociation(const tchar_t* Ext,const tchar_t* Type)
{
bool_t Result = 0;
HKEY Key;
tchar_t Base[64];
stprintf(Base,T(".%s"),Ext);
if (RegOpenKeyEx( HKEY_CLASSES_ROOT, Base, 0, ACCESS_LOAD, &Key ) == ERROR_SUCCESS)
{
tchar_t s[64];
DWORD RegSize = sizeof(s);
DWORD RegType;
if (RegQueryValueEx( Key, NULL, 0, &RegType, (LPBYTE)s, &RegSize ) == ERROR_SUCCESS && RegType == REG_SZ)
Result = TcsICmp(s,Type)==0;
RegCloseKey( Key );
}
return Result;
}
void SetFileType(const tchar_t* Type, const tchar_t* Open, const tchar_t* Icon )
{
DWORD Disp=0;
HKEY Key;
tchar_t Base[256];
if (RegCreateKeyEx( HKEY_CLASSES_ROOT, Type, 0, NULL, 0, ACCESS_SAVE, NULL, &Key, &Disp ) == ERROR_SUCCESS)
{
RegSetValueEx(Key, NULL, 0, REG_SZ, (LPBYTE)Type, (tcslen(Type)+1)*sizeof(tchar_t));
RegCloseKey(Key);
}
stprintf(Base,T("%s\\DefaultIcon"),Type);
if (RegCreateKeyEx( HKEY_CLASSES_ROOT, Base, 0, NULL, 0, ACCESS_SAVE, NULL, &Key, &Disp ) == ERROR_SUCCESS)
{
RegSetValueEx(Key, NULL, 0, REG_SZ, (LPBYTE)Icon, (tcslen(Icon)+1)*sizeof(tchar_t));
RegCloseKey(Key);
}
stprintf(Base,T("%s\\Shell\\Open\\Command"),Type);
if (RegCreateKeyEx( HKEY_CLASSES_ROOT, Base, 0, NULL, 0, ACCESS_SAVE, NULL, &Key, &Disp ) == ERROR_SUCCESS)
{
RegSetValueEx(Key, NULL, 0, REG_SZ, (LPBYTE)Open, (tcslen(Open)+1)*sizeof(tchar_t));
RegCloseKey(Key);
}
}
void TryInvalidate( HWND Wnd, RECT* r0 )
{
RECT r;
if (IsWindowVisible(Wnd))
{
GetWindowRect(Wnd,&r);
if (r0->left < r.right && r0->right > r.left &&
r0->top < r.bottom && r0->bottom > r.top)
{
// window is visible and intersects with r0
HWND Child;
POINT o;
o.x = o.y = 0;
ClientToScreen(Wnd,&o);
r.left = r0->left - o.x;
r.right = r0->right - o.x;
r.top = r0->top - o.y;
r.bottom = r0->bottom - o.y;
InvalidateRect(Wnd,&r,0);
Child = GetWindow(Wnd,GW_CHILD);
while (Child && IsWindow(Child))
{
TryInvalidate(Child,r0);
Child = GetWindow(Child,GW_HWNDNEXT);
}
}
}
}
BOOL CALLBACK EnumInvalidate( HWND Wnd, LPARAM lParam )
{
TryInvalidate(Wnd,(RECT*)lParam);
return 1;
}
void GlobalInvalidate( const rect* Rect )
{
RECT r;
r.left = Rect->x;
r.top = Rect->y;
r.right = r.left + Rect->Width;
r.bottom = r.top + Rect->Height;
#if defined(_WIN32_WCE)
if (FuncRedrawWindow) // doesn't work for mio558???
FuncRedrawWindow(NULL,&r,NULL,0x0001|0x0080); //RDW_INVALIDATE|RDW_ALLCHILDREN
else
EnumWindows(EnumInvalidate,(LPARAM)&r);
#else
RedrawWindow(NULL,&r,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN);
#endif
}
/*
#include <winioctl.h>
BOOL WINAPI KernelIoControl(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,3
LPDWORD lpBytesReturned);
#define IOCTL_HAL_REBOOT CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
void SoftReset()
{
KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL);
}
*/
void HotKeyToString( tchar_t* Out, int HotKey, int OutSize )
{
int Id = 0;
Out[0] = 0;
if (HotKey)
{
bool_t Keep = (HotKey & HOTKEY_KEEP) != 0;
if ((HotKey & HOTKEY_MASK) < 0xC1 || (HotKey & HOTKEY_MASK) > 0xCF)
{
if (HotKey & HOTKEY_WIN) { tcscat(Out,String(PLATFORM_ID,PLATFORM_KEY_WIN)); tcscat(Out,T("+")); }
if (HotKey & HOTKEY_SHIFT) { tcscat(Out,String(PLATFORM_ID,PLATFORM_KEY_SHIFT)); tcscat(Out,T("+")); }
if (HotKey & HOTKEY_CTRL) { tcscat(Out,String(PLATFORM_ID,PLATFORM_KEY_CTRL)); tcscat(Out,T("+")); }
if (HotKey & HOTKEY_ALT) { tcscat(Out,String(PLATFORM_ID,PLATFORM_KEY_ALT)); tcscat(Out,T("+")); }
}
HotKey &= HOTKEY_MASK;
if ((HotKey >= '0' && HotKey <= '9') ||
(HotKey >= 'A' && HotKey <= 'Z'))
stprintf(Out+tcslen(Out),T("%c"),HotKey);
else
if (HotKey >= 0x70 && HotKey < 0x80)
stprintf(Out+tcslen(Out),T("F%d"),HotKey-0x70+1);
else
switch (HotKey)
{
case 0x86:
Id = PLATFORM_KEY_ACTION;
break;
case VK_RETURN:
Id = PLATFORM_KEY_ENTER;
break;
case VK_ESCAPE:
Id = PLATFORM_KEY_ESCAPE;
break;
case VK_LEFT:
Id = PLATFORM_KEY_LEFT;
break;
case VK_RIGHT:
Id = PLATFORM_KEY_RIGHT;
break;
case VK_UP:
Id = PLATFORM_KEY_UP;
break;
case VK_DOWN:
Id = PLATFORM_KEY_DOWN;
break;
case VK_SPACE:
Id = PLATFORM_KEY_SPACE;
break;
case 0xC1:
case 0xC2:
case 0xC3:
case 0xC4:
case 0xC5:
case 0xC6:
case 0xC7:
case 0xC8:
case 0xC9:
case 0xCA:
case 0xCB:
case 0xCC:
case 0xCD:
case 0xCE:
case 0xCF:
stprintf(Out+tcslen(Out),String(PLATFORM_ID,PLATFORM_KEY_APP),HotKey-0xC0);
break;
default:
stprintf(Out+tcslen(Out),T("#%02X"),HotKey);
break;
}
if (Id)
tcscat(Out,String(PLATFORM_ID,Id));
if (Keep) { tcscat(Out,T("*")); }
}
}
void WaitBegin()
{
//DEBUG_MSG(DEBUG_SYS,T("WaitBegin"));
SetCursor(LoadCursor (NULL, IDC_WAIT));
WaitCursor = 1;
}
void WaitEnd()
{
//DEBUG_MSG(DEBUG_SYS,T("WaitEnd"));
SetCursor(LoadCursor (NULL, IDC_ARROW));
WaitCursor = 0;
}
const tchar_t* GetDocumentPath() { return DocPath; }
const tchar_t* GetSystemPath() { return SysPath; }
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -