HOOKFUNC BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString) { debuglog(LCF_WINDOW, __FUNCTION__ "(0x%X, \"%s\") called.\n", hWnd, lpString); if(tasflags.appLocale) { str_to_wstr(wstr, lpString, LocaleToCodePage(tasflags.appLocale)); BOOL rv = MySetWindowTextW(hWnd, wstr); DispatchMessageInternal(hWnd, WM_SETTEXT, 0, (LPARAM)wstr, false, MAF_BYPASSGAME|MAF_RETURN_OS); return rv; } BOOL rv = SetWindowTextA(hWnd, lpString); DispatchMessageInternal(hWnd, WM_SETTEXT, 0, (LPARAM)lpString, true, MAF_BYPASSGAME|MAF_RETURN_OS); return rv; }
HOOKFUNC BOOL WINAPI MySetWindowTextW(HWND hWnd, LPCWSTR lpString) { debuglog(LCF_WINDOW, __FUNCTION__ "(0x%X, \"%S\") called.\n", hWnd, lpString); BOOL rv = SetWindowTextW(hWnd, lpString); DispatchMessageInternal(hWnd, WM_SETTEXT, 0, (LPARAM)lpString, false, MAF_BYPASSGAME|MAF_RETURN_OS); return rv; }
HOOKFUNC BOOL WINAPI MySetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) { if(tasflags.forceWindowed) { if(IsWindowFakeFullscreen(hWnd)) uFlags |= SWP_NOMOVE | SWP_NOSIZE; } if(tasflags.windowActivateFlags & 2) { if(hWndInsertAfter == HWND_NOTOPMOST || hWndInsertAfter == HWND_BOTTOM || hWndInsertAfter == HWND_TOP || hWndInsertAfter == NULL) hWndInsertAfter = HWND_TOPMOST; } else { if(hWndInsertAfter == HWND_TOPMOST) hWndInsertAfter = HWND_NOTOPMOST; } BOOL rv = SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); // SetWindowPos normally sends WM_WINDOWPOSCHANGED, // but to ensure that other things we don't control can't also cause that message to get processed, // we block it in GetMessageActionFlags, and send a special version of it that won't get blocked here. WINDOWPOS pos = {hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags,}; // if(fakeDisplayValid && IsWindowFakeFullscreen(hWnd)) // DispatchMessageInternal(hWnd, WM_WINDOWPOSCHANGED-2, 0, (LPARAM)&pos); // else DispatchMessageInternal(hWnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos); return rv; }
//static bool inProcessTimers = false; void ProcessTimers() { // if(inProcessTimers) // return; // disabled, some games need to recurse // inProcessTimers = true; { DWORD time = detTimer.GetTicks(); // DWORD earliestTriggerTime = (DWORD)(time + 0x7FFFFFFF); std::vector<SetTimerData> triggeredTimers; // bool triedAgain = false; //tryAgain: EnterCriticalSection(&s_pendingSetTimerCS); std::set<SetTimerData, SetTimerDataCompare>::iterator iter; for(iter = s_pendingSetTimers.begin(); iter != s_pendingSetTimers.end();) { //// debugprintf("HOO: %d, %d\n", value.targetTime, time); // if((int)(earliestTriggerTime - value.targetTime) > 0) // earliestTriggerTime = value.targetTime; if((int)(time - iter->targetTime) >= 0) { triggeredTimers.push_back(*iter); s_pendingSetTimers.erase(iter++); } else { iter++; } } LeaveCriticalSection(&s_pendingSetTimerCS); // if(!s_frameThreadId && triggeredTimers.empty() && !triedAgain) // { //// debugprintf("HAA: %d, %d\n", earliestTriggerTime, time); // if((int)(earliestTriggerTime - time) > 0) // { //// debugprintf("HA: %d\n", earliestTriggerTime - time); // detTimer.AddDelay(earliestTriggerTime - time, FALSE, TRUE, TRUE); // triedAgain = true; // goto tryAgain; // } // } if(!(tasflags.timersMode == 0)) { for(unsigned int i = 0; i < triggeredTimers.size(); i++) { SetTimerData data = triggeredTimers[i]; debuglog(LCF_TIMERS, "timer triggered: 0x%X, 0x%X, %d, 0x%X\n", data.hWnd, data.nIDEvent, data.targetTime, data.lpTimerFunc); if(data.lpTimerFunc) { data.lpTimerFunc(data.hWnd, WM_TIMER, data.nIDEvent, time); } else { // posting it doesn't work for some reason (iji hangs on startup) //PostMessageInternal(key.hWnd, WM_TIMER, key.nIDEvent, (LPARAM)value.lpTimerFunc); DispatchMessageInternal(data.hWnd, WM_TIMER, data.nIDEvent, (LPARAM)data.lpTimerFunc, true, MAF_PASSTHROUGH|MAF_RETURN_OS); } } } triggeredTimers.clear(); } TickMultiMediaTimers(); //inProcessTimers = false; }
HOOKFUNC HWND WINAPI MyCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { debuglog(LCF_WINDOW|LCF_TODO, __FUNCTION__ "(%d,%d,%d,%d,0x%X,0x%X) called.\n", X,Y,nWidth,nHeight,dwStyle,dwExStyle); createWindowDepth++; //if(tasflags.forceWindowed && X == 0 && Y == 0 && nWidth > 640 && nHeight > 480) //{ // // check for exact matches with the screen size // // (because this might be a fake-fullscreen window) // if(nWidth == GetSystemMetrics(SM_CXSCREEN) && nHeight == GetSystemMetrics(SM_CYSCREEN)) // { // nWidth = 640; // nHeight = 480; // dwStyle &= ~WS_POPUP; // dwStyle |= WS_CAPTION; // } //} HWND oldGamehwnd = gamehwnd; ThreadLocalStuff& curtls = tls; curtls.callerisuntrusted++; curtls.treatDLLLoadsAsClient++; HWND hwnd = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); HOOKFUNC BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString); MySetWindowTextA(hwnd, lpWindowName); curtls.treatDLLLoadsAsClient--; curtls.callerisuntrusted--; debuglog(LCF_WINDOW, __FUNCTION__ " made hwnd = 0x%X.\n", hwnd); #ifdef EMULATE_MESSAGE_QUEUES if(hwnd) { MessageQueue& mq = curtls.messageQueue; // if(mq.attachedWindows.empty()) // mq.attachedWindows.insert((HWND)NULL); // so PostMessage with a NULL HWND knows to post to the current thread mq.attachedWindows.push_back(hwnd); } #endif createWindowDepth--; if(hwnd && createWindowDepth == 0) { if(!oldGamehwnd) { curtls.createdFirstWindow = true; gamehwnd = hwnd; } WNDPROC oldProc = (WNDPROC)MyGetWindowLongA(hwnd, GWL_WNDPROC); if(!oldProc) { WNDCLASSEXA cls = { sizeof(WNDCLASSEXA) }; GetClassInfoExA(hInstance, lpClassName, &cls); if(cls.lpfnWndProc) { oldProc = cls.lpfnWndProc; debuglog(LCF_WINDOW|LCF_TODO, "had to retrieve wndproc from wndclass (\"%s\") for some reason...\n", lpClassName); } } debuglog(LCF_WINDOW, "oldProc[0x%X] = 0x%X\n", hwnd, oldProc); hwndToOrigHandler[hwnd] = oldProc; SetWindowLongA(hwnd, GWL_WNDPROC, (LONG)MyWndProcA); cmdprintf("HWND: %d", hwnd); if(tasflags.windowActivateFlags & 2) { // hmm, I'm getting desyncs all of a sudden... // the wintaser window flickers every time it happens // but I don't know what could be causing that. // well, maybe it's happening less now for some reason, // but it's something to watch for (possible bugs here) // tasflags.windowActivateFlags ^= 2; // ShowWindow(hwnd, TRUE); SetForegroundWindow(hwnd); //SetActiveWindow(hwnd); //SetFocus(hwnd); SetWindowPos(hwnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); // tasflags.windowActivateFlags ^= 2; } else { SetWindowPos(hwnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); } SetActiveWindow(hwnd); // FIXME TEMP maybe need to hook SetActiveWindow / SetForegroundWindow etc instead DispatchMessageInternal(hwnd, WM_ACTIVATE, WA_ACTIVE, (LPARAM)hwnd); DispatchMessageInternal(hwnd, WM_SETFOCUS, 0, 0); /*WINDOWPOS pos = { hwnd,//HWND hwnd; hWndParent,//HWND hwndInsertAfter; X,//int x; Y,//int y; nWidth,//int cx; nHeight,//int cy; SWP_NOREDRAW|SWP_NOACTIVATE|SWP_FRAMECHANGED,//UINT flags; };*/ //DispatchMessageInternal(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos); CREATESTRUCTA create = { lpParam,//LPVOID lpCreateParams; hInstance,//HINSTANCE hInstance; hMenu,//HMENU hMenu; hWndParent,//HWND hwndParent; nHeight,//int cy; nWidth,//int cx; Y,//int y; X,//int x; dwStyle,//LONG style; lpWindowName,//LPCTSTR lpszName; lpClassName,//LPCTSTR lpszClass; dwExStyle,//DWORD dwExStyle; }; DispatchMessageInternal(hwnd, WM_CREATE, 0, (LPARAM)&create); } return hwnd; }
HOOKFUNC HWND WINAPI MyCreateWindowExW(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { debuglog(LCF_WINDOW, __FUNCTION__ " called.\n"); createWindowDepth++; HWND oldGamehwnd = gamehwnd; ThreadLocalStuff& curtls = tls; curtls.callerisuntrusted++; curtls.treatDLLLoadsAsClient++; HWND hwnd = CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); curtls.treatDLLLoadsAsClient--; curtls.callerisuntrusted--; debuglog(LCF_WINDOW, __FUNCTION__ " made hwnd = 0x%X.\n", hwnd); #ifdef EMULATE_MESSAGE_QUEUES if(hwnd) { MessageQueue& mq = curtls.messageQueue; // if(mq.attachedWindows.empty()) // mq.attachedWindows.insert((HWND)NULL); // so PostMessage with a NULL HWND knows to post to the current thread mq.attachedWindows.push_back(hwnd); } #endif createWindowDepth--; #if 0 // FIXME should be enabled but currently breaks Iji due to some bug if(hwnd && createWindowDepth == 0) { if(!oldGamehwnd) { curtls.createdFirstWindow = true; gamehwnd = hwnd; } //WNDCLASSEXA cls = { sizeof(WNDCLASSEXA) }; //GetClassInfoExA(hInstance, lpClassName, &cls); WNDPROC oldProc = (WNDPROC)MyGetWindowLongW(hwnd, GWL_WNDPROC); if(!oldProc) { WNDCLASSEXW cls = { sizeof(WNDCLASSEXW) }; GetClassInfoExW(hInstance, lpClassName, &cls); if(cls.lpfnWndProc) { oldProc = cls.lpfnWndProc; debuglog(LCF_WINDOW|LCF_TODO, "had to retrieve wndproc from wndclass (\"%S\") for some reason...\n", lpClassName); } } debuglog(LCF_WINDOW, "oldProc[0x%X] = 0x%X\n", hwnd, oldProc); debuglog(LCF_WINDOW, "oldProc[0x%X] = 0x%X\n", hwnd, oldProc); hwndToOrigHandler[hwnd] = oldProc; SetWindowLongW(hwnd, GWL_WNDPROC, (LONG)MyWndProcW); cmdprintf("HWND: %d", hwnd); if(tasflags.windowActivateFlags & 2) { // hmm, I'm getting desyncs all of a sudden... // the wintaser window flickers every time it happens // but I don't know what could be causing that. // well, maybe it's happening less now for some reason, // but it's something to watch for (possible bugs here) // tasflags.windowActivateFlags ^= 2; // ShowWindow(hwnd, TRUE); SetForegroundWindow(hwnd); //SetActiveWindow(hwnd); //SetFocus(hwnd); SetWindowPos(hwnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); // tasflags.windowActivateFlags ^= 2; } else { SetWindowPos(hwnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE); } SetActiveWindow(hwnd); // FIXME TEMP maybe need to hook SetActiveWindow / SetForegroundWindow etc instead DispatchMessageInternal(hwnd, WM_ACTIVATE, WA_ACTIVE, (LPARAM)hwnd, false); DispatchMessageInternal(hwnd, WM_SETFOCUS, 0, 0, false); /*WINDOWPOS pos = { hwnd,//HWND hwnd; hWndParent,//HWND hwndInsertAfter; X,//int x; Y,//int y; nWidth,//int cx; nHeight,//int cy; SWP_NOREDRAW|SWP_NOACTIVATE|SWP_FRAMECHANGED,//UINT flags; };*/ //SendMessageW(hwnd, toggleWhitelistMessage(WM_WINDOWPOSCHANGED), 0, (LPARAM)&pos); CREATESTRUCTW create = { lpParam,//LPVOID lpCreateParams; hInstance,//HINSTANCE hInstance; hMenu,//HMENU hMenu; hWndParent,//HWND hwndParent; nHeight,//int cy; nWidth,//int cx; Y,//int y; X,//int x; dwStyle,//LONG style; lpWindowName,//LPCTSTR lpszName; lpClassName,//LPCTSTR lpszClass; dwExStyle,//DWORD dwExStyle; }; DispatchMessageInternal(hwnd, WM_CREATE, 0, (LPARAM)&create, false); // trying to get the stupid splash screen to work, not sure how to fake the paint event well enough for it //InvalidateRect(hwnd, NULL, TRUE); //PostMessageInternal(hwnd, WM_PAINT, 0, 0, false); //InvalidateRect(hwnd, NULL, TRUE); //DispatchMessageInternal(hwnd, WM_PAINT, 0, 0, false); } #endif return hwnd; }