MapX 在執行 Zoom 時有時會顯得非常慢,并且是一層一層繪制出的,有一種想法是如果可以將繪制程序先繪制到記憶體中然后再一次性拷貝到螢屏上,這不但能節省一些時間,也可以防止閃爍。不知道如何讓MapX繪制時直接繪制到記憶體中?
uj5u.com熱心網友回復:
僅供參考:
VOID Paint(HDC hdc) {
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
case WM_PAINT:
hdc=BeginPaint(hWnd, &ps);
BitBlt(memDC,0,0,width,height,hdc,0,0,SRCCOPY);
Paint(memDC);
BitBlt(hdc,0,0,width,height,memDC,0,0,SRCCOPY);
EndPaint(hWnd, &ps);
return 0;
}
global_hdc=GetDC(hWnd);
memDC=CreateCompatibleDC(NULL);
HBITMAP bmp=CreateCompatibleBitmap(global_hdc,width,height);
HBITMAP OldBmp=(HBITMAP)SelectObject(memDC,bmp);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
SelectObject(global_hdc,OldBmp);
DeleteObject(bmp);
DeleteDC(memDC);
ReleaseDC(hWnd,global_hdc);
uj5u.com熱心網友回復:
@趙4老師問題在于
1 hdc=BeginPaint(hWnd, &ps);
2 BitBlt(memDC,0,0,width,height,hdc,0,0,SRCCOPY);
3 Paint(memDC);
4 BitBlt(hdc,0,0,width,height,memDC,0,0,SRCCOPY);
5 EndPaint(hWnd, &ps);
在第 2步完成后,MapX 控制元件在執行縮放命令(Zoom)時,會自動往hdc 繪制地圖,并同時輸出到視窗。而不是在memDC 上繪制,我是希望 memDC 能替換 mapx 的DC
(既通過 mapxCtr.GetDC()獲取的 CDC),當MapX 執行繪制操作時會知道memDC 中,繪制完成后我在根據繪制結束訊息拷貝到螢屏上去
uj5u.com熱心網友回復:
WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/uj5u.com熱心網友回復:
@趙4老師感謝您的熱情幫助,WinAPIOverride 看到 在一次縮放程序中MapX 會一直往其DC(簡稱 DC_Map)中繪制資訊,程序包括GetDC—— IsWindow—— ReleaseDC() 但是這些資訊對我的目標無有幫助,我是希望在縮放的程序中能用我創建的memDC 來替換DC_Map 這樣才能達到不閃爍的目的
uj5u.com熱心網友回復:
使用WinAPIOverride,Hook MapX對應行程的GetDC,讓其回傳你的memDC,……uj5u.com熱心網友回復:
又或者MapX是開源的,直接修改相關源代碼使用memDCuj5u.com熱心網友回復:
@趙4老師使用WinAPIOverride,Hook MapX對應行程的GetDC,讓其回傳你的memDC,……
對于這個我理解了 ,但是執行起來還有很大難度,是否可以直接通過代碼方式完成 DC_map 到 memDC 的替換呢。還請趙老師不吝賜教,感恩!
(另、MapInfo 也可以達到縮放時一次性顯示出來的效果,不知MapInfo 是否也采用了 Hook 的方式)
uj5u.com熱心網友回復:
注入一例,僅供參考:/*
Application: Code Injection in Explorer
Author: @_RT
Compiled on: Feb 2014
URL:http://www.codeproject.com/Tips/732044/Code-Injection-2
We will see the different steps involved to perform a code injection into an already running process.
Following are the quick steps through the process of injection.
1.Get the API addresses that you will be calling from the injected code.
2.Prepare shell code of your function that you want to get executed from the injected process.
3.Get the process ID of the running process that you wish to inject into by enumerating through the
list of processes or by finding the process's window (in case it's a GUI application) by class name or title.
4.Open the process using its Pid with All Access rights.
5.Allocate different memory spaces in the process that you are going to inject to with desired access
rights for holding different segments of your shell code.
Code part (executable instructions)
Data part (strings, function parameters, etc.)
6.Write the allocated memories with the respective values (code and data).
7.Call CreateRemoteThread API and pass to it the start of allocated memory address where you have
written your shell code from the process we are injecting.
*/
#include <windows.h>
#pragma comment(lib,"user32.lib")
LPVOID addr;
LPVOID addr2;
BOOL InjectExecutable(DWORD dwPid,LPVOID si,LPVOID pi,int sisize,int pisize)
{
LPVOID hNewModule;
HANDLE hProcess;
CHAR S[] = { "C:\\Windows\\system32\\notepad.exe" };
BYTE byt[] = {0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68};
//push 0 , push 0, push 0, push 1, push 0, push 0, push 0, push 0xXXXXXXXX
BYTE byt2[] = {0xE8};//call 0xXXXXXXXX
BYTE byt3[] = {0x68};//push 0xXXXXXXXX
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess == NULL)
{
return FALSE;
}
LPVOID staddr = VirtualAllocEx(hProcess, NULL, sizeof(S), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, staddr, S, sizeof(S), NULL);
LPVOID fnaddr = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, fnaddr, pi, sisize, NULL);
LPVOID fnaddr2 = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, fnaddr2, si, pisize, NULL);
hNewModule = VirtualAllocEx(hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (hNewModule == NULL)
{
return FALSE;
}
LPTHREAD_START_ROUTINE strtaddr = (LPTHREAD_START_ROUTINE)hNewModule;
WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
WriteProcessMemory(hProcess, hNewModule, &fnaddr, sizeof(fnaddr), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr)); // push &pi ;lpProcessInformation
WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
WriteProcessMemory(hProcess, hNewModule, &fnaddr2, sizeof(fnaddr2), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr2)); // push &si ;lpStartupInfo
WriteProcessMemory(hProcess, hNewModule, byt, sizeof(byt), NULL); // push 0 , push 0, push 0, push 1, push 0, push 0, push 0, push 0xXXXXXXXX==&S[0];"C:\\Windows\\system32\\notepad.exe"
hNewModule = (LPVOID)((int)hNewModule + sizeof(byt)); // lpCurrentDirectory,lpEnvironment,dwCreationFlags,bInheritHandles,lpThreadAttributes,lpProcessAttributes,lpCommandLine,lpApplicationName
WriteProcessMemory(hProcess, hNewModule, &staddr, sizeof(staddr), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(staddr));
WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2)); // call CreateProcessA
addr = (LPVOID)((int)addr - ((int)hNewModule + 4));
WriteProcessMemory(hProcess, hNewModule, &addr, sizeof(addr), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(addr));
WriteProcessMemory(hProcess, hNewModule, byt, 2, NULL);
hNewModule = (LPVOID)((int)hNewModule + 2); // push 0 ;DWORD dwExitCode // exit code for this thread
WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2)); // call ExitThread
addr2 = (LPVOID)((int)addr2 - ((int)hNewModule + 4));
WriteProcessMemory(hProcess, hNewModule, &addr2, sizeof(addr2), NULL);
CreateRemoteThread(hProcess, 0, 0, strtaddr, NULL, 0, NULL);
return TRUE;
}
int main()
{
_STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
DWORD dwPid;
HMODULE ldlib = LoadLibraryA("Kernel32.dll");
addr = GetProcAddress(ldlib, "CreateProcessA");
addr2 = GetProcAddress(ldlib, "ExitThread");
HWND hWnd1=FindWindow(NULL, "Program Manager");
if (NULL==hWnd1) {
return 1;
}
GetWindowThreadProcessId(hWnd1, &dwPid);
InjectExecutable(dwPid,&si,&pi,sizeof(si),sizeof(pi));
return 0;
}
uj5u.com熱心網友回復:
趙老師威武轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/85578.html
標籤:界面
上一篇:多執行緒訪問同一資料庫,資料庫報2006和2013錯誤
下一篇:記憶體分配與釋放問題請教
