在桌面上畫圖的問題 |
尚未結案
|
shinnuei
一般會員 ![]() ![]() 發表:32 回覆:48 積分:21 註冊:2002-03-13 發送簡訊給我 |
各位先進好:
小弟現在利用以下的方式在視窗上畫圖。
dc = GetDC(0); ScreenCanvas->Handle = dc; ScreenCanvas->Brush->Style=bsClear; ScreenCanvas->TextOut(300,300,"訊息");但是這個畫圖方式,如果有開任何視窗,則會畫在上面, 但是我要把他畫在真正的桌面上,而不是目前的畫面上, 請問要如何做呢? 另外一點就是如何把他清除成沒有繪圖之前的畫面呢? 比如現在在 x:300,y:300 的地方畫了"訊息"兩個字… 我想要把他清除掉,再畫上其他的字,要怎麼做呢? |
aquarius
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:3 回覆:347 積分:330 註冊:2003-05-21 發送簡訊給我 |
用 DELPHI 寫個範例給你看看
var hDesktop : THandle ; s : string ; function EnumChidProc(h:THandle;lp:DWORD):bool ; stdcall ; var cBuf : array[0..255] of char ; begin GetClassName(h,cBuf,255) ; if StrComp(cBuf,'SysListView32')=0 then begin hDesktop:=h ; Result:=false ; exit ; end ; Result:=true ; end ; procedure TForm1.Button1Click(Sender: TObject); var h : THandle ; dc : HDC ; begin h:=FindWindow('Progman',nil) ; EnumChildWindows(h,@EnumChidProc,0) ; caption:=inttohex(hDesktop,8) ; dc:=GetDC(hDesktop) ; s:='This is a test.' ; Windows.TextOut(dc,10,10,pchar(s),length(s)) ; ReleaseDC(hDesktop,dc) ; end; procedure TForm1.Button2Click(Sender: TObject); var r : TRect ; begin r:=rect(10,10,200,50) ; InvalidateRect(hDesktop,@r,true) ; end;...Aquarius
------
水瓶男的blog: http://791909.blogspot.com |
shinnuei
一般會員 ![]() ![]() 發表:32 回覆:48 積分:21 註冊:2002-03-13 發送簡訊給我 |
TO aquarius:
很抱歉 aquarius,delphi 小弟實在不太懂,不過小弟照著語法去翻成 C++ Builder 的用法,
遇到一些問題
function EnumChidProc(h:THandle;lp:DWORD):bool ; stdcall ; var cBuf : array[0..255] of char ; begin GetClassName(h,cBuf,255) ; if StrComp(cBuf,'SysListView32')=0 then begin hDesktop:=h ; Result:=false ; exit ; end ; Result:=true ; end ;上述程式碼標示成紅色的地方是那一隻程式呢?我用工作管理員和 WinSight32 都找不到… 因為上述副程式顯然要找這隻程式。 不過我直覺要清除畫面的關鍵應該是在InvalidateRect 這個API,但是我直接用 dc = GetDC(0); ret = InvalidateRect(dc,&Rect(0,0,600,600),true); 結果卻得到 false 的回傳值. 請問要怎麼做呢? |
aquarius
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:3 回覆:347 積分:330 註冊:2003-05-21 發送簡訊給我 |
Progman 是桌面的 CLASS
SysListView32 則是其下的 Child InvalidateRect 傳入的第一個參數是 hWnd, 不是 HDC
這是用來重繪指定視窗中的指定區域, 第一個參數傳 0 則會整個畫面重繪. (我那段程式在 Windows 2000 下試過沒問題, 但不確定 Windows 98 / ME / XP 下的 Class name 都相同, 請自行確認.) ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com |
shinnuei
一般會員 ![]() ![]() 發表:32 回覆:48 積分:21 註冊:2002-03-13 發送簡訊給我 |
TO aquarius:
再次請教,Delphi 裡的 @ 是什麼意思呢?
procedure TForm1.Button1Click(Sender: TObject); var h : THandle ; dc : HDC ; begin h:=FindWindow('Progman',nil) ; EnumChildWindows(h,@EnumChidProc,0) ; caption:=inttohex(hDesktop,8) ; dc:=GetDC(hDesktop) ; s:='This is a test.' ; Windows.TextOut(dc,10,10,pchar(s),length(s)) ; ReleaseDC(hDesktop,dc) ; end;上面這段程式碼有呼叫到 EnumChildWindows 而裡面有帶一個參數 @EnumChidProc 這應該是呼叫 EnumChidProc ,但是這個函式的傳回值是 boolean 我查BCB Help關 於 EnumChildWindows資料如下: BOOL EnumChildWindows( HWND hWndParent, // handle to parent window WNDENUMPROC lpEnumFunc, // pointer to callback function LPARAM lParam // application-defined value );第二個值是指到一個 callback 的函數,這個用法小弟就沒用過了, |
aquarius
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:3 回覆:347 積分:330 註冊:2003-05-21 發送簡訊給我 |
|
shinnuei
一般會員 ![]() ![]() 發表:32 回覆:48 積分:21 註冊:2002-03-13 發送簡訊給我 |
TO aquarius:
CALLBACK 現在己經可以了…原來 BCB 使用 CALLBACK function 的方式和 delphi 差這麼多.
宣告:
bool CALLBACK EnumChidProc(HWND, LPARAM);
CALLBACK函式
bool CALLBACK EnumChidProc(HWND h, LPARAM a) { char cBuf[256]; GetClassName(h, cBuf, 256); if (StrComp(cBuf,"SysListView32")==0) { hDesktop=h; return false; } return true; }呼叫方式: EnumChildWindows(h, reinterpret_cast |
shinnuei
一般會員 ![]() ![]() 發表:32 回覆:48 積分:21 註冊:2002-03-13 發送簡訊給我 |
|
aquarius
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:3 回覆:347 積分:330 註冊:2003-05-21 發送簡訊給我 |
|
shinnuei
一般會員 ![]() ![]() 發表:32 回覆:48 積分:21 註冊:2002-03-13 發送簡訊給我 |
To aquarius:
不好意思,一直麻煩你,其他人可能對這個主題較沒興趣。
小弟現在是找一個可以解決問題的方法,然後由這個方法去
寫程式其他的部份,只是現在小弟對delphi不熟,所以想將
您的程式碼翻成 BCB 下去執行,但是目前卡在桌面繪圖的
TextOut 不會輸出,相對的 InvalidateRect 也不能執行,
小弟試過用0去代第一個參數的確會Refresh整個營幕,但用
其他的handle 還是會Refresh整個畫面,小弟再試試看好了
,謝謝. 發表人 - shinnuei 於 2003/11/25 20:11:44
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |