platform_win32.c

来自「betaplayer_0.096源码 tcpmp老版本」· C语言 代码 · 共 2,601 行 · 第 1/5 页

C
2,601
字号
	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

int FileDate( const tchar_t* Path )
{
	int Date = -1;
	HANDLE Find;
	SYSTEMTIME Time;
	WIN32_FIND_DATA FindData;

	Find = FindFirstFile( Path, &FindData );
	if (Find != INVALID_HANDLE_VALUE)
	{
		if (FileTimeToSystemTime(&FindData.ftCreationTime,&Time))
			Date = (int)Time.wYear*10000+(int)Time.wMonth*100+(int)Time.wDay;
		FindClose(Find);
	}
	return Date;
}

file FileOpen( const tchar_t* Path, bool_t Write )
{
	return (file)CreateFile(Path,Write?GENERIC_WRITE:GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,Write?CREATE_ALWAYS:OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
}

int FileSeek( file File, int Ofs, int Mode)
{
	switch (Mode)
	{
	case SEEK_SET: Mode = FILE_BEGIN; break;
	case SEEK_CUR: Mode = FILE_CURRENT; break;
	case SEEK_END: Mode = FILE_END; break;
	default: return -1;
	}
	return SetFilePointer((HANDLE)File,Ofs,NULL,Mode);
}

int FileRead( file File, void* p, int n)
{
	DWORD m = (DWORD)-1;
	ReadFile((HANDLE)File,p,n,&m,NULL);
	return m;
}

int FileWrite( file File, const void* p, int n)
{
	DWORD m = (DWORD)-1;
	WriteFile((HANDLE)File,p,n,&m,NULL);
	return m;
}

void FileClose( file File )
{
	CloseHandle((HANDLE)File);
}

void FilePrintf( file File, const tchar_t* Msg,...)
{
	tchar_t* s0 = (tchar_t*)Alloc(2048*sizeof(tchar_t));
	tchar_t* s1 = s0;
	tchar_t* s2 = s0+1024;
	vstprintf( s1, Msg, (VA_LIST)(&Msg+1) );
	while (*s1)
	{
		if (*s1 == 10)
			*(s2++) = 13;
		*(s2++) = *(s1++);
	}
	*s2=0;
	TcsToStr((char*)s0,s0+1024,1024*sizeof(tchar_t));
	FileWrite(File,s0,strlen((char*)s0)*sizeof(char));
	Free(s0);
}

void StreamPrintf( stream* Stream, bool_t UTF8, const tchar_t* Msg,...)
{
	tchar_t* s0 = (tchar_t*)Alloc(2048*sizeof(tchar_t));
	tchar_t* s1 = s0;
	tchar_t* s2 = s0+1024;
	vstprintf( s1, Msg, (VA_LIST)(&Msg+1) );
	while (*s1)
	{
		if (*s1 == 10)
			*(s2++) = 13;
		*(s2++) = *(s1++);
	}
	*s2=0;

	if (UTF8)
		TcsToUTF8((char*)s0,s0+1024,1024*sizeof(tchar_t));
	else
		TcsToStr((char*)s0,s0+1024,1024*sizeof(tchar_t));

	Stream->Write(Stream,s0,strlen((char*)s0)*sizeof(char));
	Free(s0);
}

void Dump()
{
	file File;
	tchar_t Path[MAXPATH];
	stprintf(Path,T("%s\\dump.txt"),DocPath);

	File = FileOpen(Path,1);
	if (File)
	{
		NodeDump(File);
		FileClose(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;
	file* File;
	tchar_t Path[MAXPATH];
	stprintf(Path,T("%s\\crash.txt"),DocPath);

	File = FileOpen(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];

		FilePrintf(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);
		FilePrintf(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");
			FilePrintf(File,T("\n%s %08x"),Name,Record->ExceptionInformation[1]);
			if (NodeLocate((void*)Record->ExceptionInformation[1],DllName,&DllBase))
				FilePrintf(File,T(" (%s:%08x)"),DllName,DllBase);
		}
		
		// context

		FilePrintf(File,T("\n\ncpu dump:"));

		for (r=Reg;r->Name;++r)
		{
			void* Ptr = *(void**)(Context+r->Ofs);

			FilePrintf(File,T("\n%-5s = %08x"),r->Name,Ptr);

			if (NodeLocate(Ptr,DllName,&DllBase))
				FilePrintf(File,T(" (%s:%08x)"),DllName,DllBase);
		}

		if (r->Ofs >= 0)
		{
			FilePrintf(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;

					FilePrintf(File,T("\n%08x %08x"),Stack,Ptr);

					if (NodeLocate(Ptr,DllName,&DllBase))
						FilePrintf(File,T(" (%s:%08x)"),DllName,DllBase);
				}
				else
					FilePrintf(File,T("\n%08x ????????"),Stack);
			}
		}

		FilePrintf(File,T("\n\nnode dump:\n"));

		NodeDump(File);

		FileClose(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 + =
减小字号Ctrl + -
显示快捷键?