sendMessage 的 WM_COPYDATA 偷偷做了什麼事? |
答題得分者是:aftcast
|
boy330077
一般會員 ![]() ![]() 發表:39 回覆:59 積分:19 註冊:2009-10-15 發送簡訊給我 |
EXEA :
[code delphi] const WM_MY_MESSAGE = WM_APP 99; type Tfrm_EXEA_Main = class(TForm) Label1: TLabel; ListBox1: TListBox; private { Private declarations } procedure CopyData(var Msg: TWMCopyData); message WM_COPYDATA; procedure MyReceive(var Msg: TWMCopyData); message WM_MY_MESSAGE; public { Public declarations } end; [/code]procedure Tfrm_EXEA_Main.CopyData(var Msg: TWMCopyData); begin ListBox1.Items.Append('CopyData is ' PChar(Msg.CopyDataStruct.lpData)); end; procedure Tfrm_EXEA_Main.MyReceive(var Msg: TWMCopyData); begin ListBox1.Items.Append('MyReceive is ' PChar(Msg.CopyDataStruct.lpData)); end; 兩個副程式 幾乎一樣 只有後面的訊息常數 不同 但是 WM_MY_MESSAGE 卻會錯誤(似乎是位置錯誤) 懷疑 是不是 WM_COPYDATA 在哪裡已經被處理過? 我卻找不到 |
boy330077
一般會員 ![]() ![]() 發表:39 回覆:59 積分:19 註冊:2009-10-15 發送簡訊給我 |
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
關鍵點在 sendmessage/postmessage 是在哪裡發生的?
別的應用程式? 同一隻應用程式不同thread? 不過,先可以簡言之,WM_COPYDATA 之所以叫 WM_COPYDATA 是因為它是 windows系統創的,windows系統怎麼處理它,是windows特有的能力。而你的自訂訊息,是你寫的,問題點極可能是你要傳的訊息是從別的應用程式送來的… ???
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
boy330077
一般會員 ![]() ![]() 發表:39 回覆:59 積分:19 註冊:2009-10-15 發送簡訊給我 |
沒錯 EXEA EXEB 分開
EXEB 有兩個按鈕 分別 procedure Tfrm_EXEB_Main.Button1Click(Sender: TObject); begin MySendMessage(WM_COPYDATA); end; procedure Tfrm_EXEB_Main.Button2Click(Sender: TObject); begin MySendMessage(WM_MY_MESSAGE); end; procedure Tfrm_EXEB_Main.MySendMessage(msg: Cardinal); var h:HWND; copyDataStruct:TCopyDataStruct; begin h:=FindWindow('Tfrm_EXEA_Main', 'EXEA'); with copyDataStruct do begin dwData := 0; cbData := (Length(str) 1)*2; lpData := PChar(str); SendMessage(h, msg, Integer(Handle), Integer(@copyDataStruct)); end; end;
按鈕1 EXE1 能收到正確字串 按鈕2 錯誤 ![]() |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
ok,你想知道 wm_copydata 偷偷做了什麼?
我把我所知道的部份讓你知道。但我講的不是全部,全部的細節可能 微軟的工程師才會知道。 因為不同的 process 有著自己的 記憶體空間,原則上是2g (例外不說),就是說一個應用程式有 2g 個門牌號碼,裡面放著程式碼與資料。我們假設 exeA 的 記憶體位址 5000的地方,放了一個字串叫 " hello world"。 而 exeB 的記憶體裡,它的 5000的地方放 "Im nerd"。 當你在 exeB的執行環境下,你copy了 5000的地址,當作要送給 exeA的內容。 發生什麼事? 你在 exeA的地方,收了message,裡面提到 5000的地址有資料,請去拿。但…… 此刻是在 exeA裡,去5000拿,是會拿到 "hello world",不會拿得到 exeB家裡的 im nerd 的。 此 5000地址,不是那個5000的地址! 於是,若不幸的,5000地址之於 exeA 是一個禁區,那就會跳該死的AV。 那麼WM_COPYData它幹了啥? windows 系統自己訂的東西,無非就是要讓 不同 proceess 可以溝通。於是當 exeB的5000的位址送過去時,windows會偷偷的把 exeb 的內容印射到 exeA可以讀到的地址,這裡當然很玄的技巧。但你就想像,windows讓接收訊息的那方可以神奇的去抓別人家裡的資料。 若你真的不想用 windows提供的這個方法。你可以
1/ 寫一個dll,並設定該dll可以分享資料,然後讓 exea 與 exeb 都載入該dll 2/ 也可以用 socket 方式 3/ 也可以用 fiemapping的方式 4/ name pipe 方式
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
boy330077
一般會員 ![]() ![]() 發表:39 回覆:59 積分:19 註冊:2009-10-15 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |