I've done a DLL that contains a menu using ImGui, but there is one problem I can't solve. When the DLL is injected in another application everything works as usual, but when I try to open something that requires administrator rights, menu goes unresponsive. The DLL is injected in a task that has been run with administrator rights. I couldn't get a way to fix this issue. I've tried recreating ImGui window using this but it didn't work.
void RecreateImGuiWindow() {
ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX9_Init(pDevice);
isMenuVisible = true;
}
Here's the source code
bool InitialD3D(HWND hWnd) {
if ((pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) {
return false;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice) < 0) {
return false;
}
ImGui::CreateContext();
ImGui_ImplWin32_Init(hWnd);
ImGui_ImplDX9_Init(pDevice);
// Set ImGui style
SetImGuiStyle();
return true;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (ImGui_ImplWin32_WndProcHandler(hWnd, message, wParam, lParam))
return 1;
switch (message) {
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void CreateImGuiWindow() {
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc, 0L, 0L, GetModuleHandle(0), 0, 0, 0, 0, L"ImGuiWindow", 0 };
RegisterClassEx(&wc);
hwnd = CreateWindow(L"ImGuiWindow", L"MENU", WS_POPUP | WS_VISIBLE, 500, 400, 500, 400, 0, 0, wc.hInstance, 0);
//Window Location and Size
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
if (!InitialD3D(hwnd)) {
}
}
void ShowImGuiWindow() {
ShowWindow(hwnd, SW_SHOW);
}
void HideImGuiWindow() {
ShowWindow(hwnd, SW_HIDE);
}
void DestroyImGuiWindow() {
ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
pDevice->Release();
pD3D->Release();
DestroyWindow(hwnd);
UnregisterClass(L"ImGuiWindow", GetModuleHandle(0));
}
DWORD WINAPI MainThread(LPVOID lpParam) {
CreateImGuiWindow();
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT) {
if (PeekMessage(&msg, 0, 0U, 0U, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
if ((GetAsyncKeyState(VK_MENU) & 0x8000) && (GetAsyncKeyState('H') & 0x8000)) {
RecreateImGuiWindow();
Sleep(200);
}
if ((GetAsyncKeyState(VK_MENU) & 0x8000) && (GetAsyncKeyState('I') & 0x8000)) {
isMenuVisible = !isMenuVisible;
if (isMenuVisible) {
ShowImGuiWindow();
}
else {
HideImGuiWindow();
}
Sleep(200);
}
if (isMenuVisible) {
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
RenderGui();
ImGui::EndFrame();
pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 1.0f, 0);
pDevice->BeginScene();
ImGui::Render();
pDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
pDevice->EndScene();
//ImGui::EndFrame();
//pDevice->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
//pDevice->BeginScene();
//ImGui::Render();
//ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
//pDevice->EndScene();
pDevice->Present(0, 0, 0, 0);
}
}
DestroyImGuiWindow();
return 0;
}