全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2025
推到 Plurk!
推到 Facebook!

在桌面上畫圖的問題

尚未結案
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-11-16 17:06:53 IP:61.221.xxx.xxx 未訂閱
各位先進好: 小弟現在利用以下的方式在視窗上畫圖。
  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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-11-17 10:27:20 IP:211.23.xxx.xxx 未訂閱
用 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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-11-17 20:52:57 IP:61.221.xxx.xxx 未訂閱
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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-11-18 09:38:35 IP:211.23.xxx.xxx 未訂閱
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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-11-19 21:30:50 IP:61.221.xxx.xxx 未訂閱
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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-11-20 09:42:14 IP:211.23.xxx.xxx 未訂閱
Delphi 的 @ 就是取位址, 和 C 的 & 相同. Callback function 就是像我範例中那樣用呀, 把函數的位址傳入, 那個程式會自動 CALL 進指定的函數中. ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-11-21 22:04:11 IP:61.221.xxx.xxx 未訂閱
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 (EnumChidProc), 0); 不過現在又有一個問題,BCB顯然沒有 Windows 這個物件,這是一個什麼物件呢? 就只差最後兩個步驟了,煩請 aquarius 再指教.
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-11-23 15:25:07 IP:61.221.xxx.xxx 未訂閱
各位先進好: 小弟己將程式碼放上來了,連結如下 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=40951 請幫忙看看那裡有問題.謝謝
aquarius
資深會員


發表:3
回覆:347
積分:330
註冊:2003-05-21

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-11-24 10:09:31 IP:211.23.xxx.xxx 未訂閱
你的程式還有什麼問題嗎? TextOut 只是把字畫上去, 看你原本用什麼方法畫就用那方法即可. 不一定要和我 DELPHI 的程式一樣啦!! 其實這程式的重點, 也不過就是找到桌面的 DC, 以及如何用 InvalidateRect 這個 Function. ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-11-25 20:06:41 IP:61.221.xxx.xxx 未訂閱
To aquarius: 不好意思,一直麻煩你,其他人可能對這個主題較沒興趣。 小弟現在是找一個可以解決問題的方法,然後由這個方法去 寫程式其他的部份,只是現在小弟對delphi不熟,所以想將 您的程式碼翻成 BCB 下去執行,但是目前卡在桌面繪圖的 TextOut 不會輸出,相對的 InvalidateRect 也不能執行, 小弟試過用0去代第一個參數的確會Refresh整個營幕,但用 其他的handle 還是會Refresh整個畫面,小弟再試試看好了 ,謝謝. 發表人 - shinnuei 於 2003/11/25 20:11:44
系統時間:2024-05-04 23:45:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!