フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1] 2
トピック: デスクトップにお絵かき (DelWiki)
RAN
メンバー
投稿数: 34
デスクトップにお絵かき (DelWiki)
on: 2013/04/16 21:33 Tue

使うのはGetDC、SetPixel、ReleaseDCだけです。 再描画されればそこに描いた線は消えます。

procedure TForm1.FormCreate(Sender: TObject);
var
DC: THandle; {デバイスコンテキストハンドル}
i: integer;
begin
DC := GetDC(0);
for i:=1 to 800 do
SetPixel(DC, i, i, 255);
//必ず解放
ReleaseDC(0, DC);
end;
Mr.XRAY
メンバー
投稿数: 192
デスクトップにアイコンを描画する祭の透明化処理
on: 2013/05/05 18:06 Sun

>再描画されればそこに描いた線は消えます。

てなわけで,描画内容は持続的ではないのですが,ちょっと相談が.
DetDC で得られるハンドルは,モニタのデバイスコンテキスト(仮想画面全体)のハンドルです.

それで,例えば,マウスのアイコン(カーソル) の画像を取得します.
それをデスクトップに描画するとですね.以下のコードだと,下の左の図のようになります.
これを,下の右の図 (合成図) のようにしたいのです.

procedure TForm1.Button1Click(Sender: TObject);
var
hDesktopDC : HDC;
hCur : HCURSOR;
begin

hDesktopDC := GetDC(0);
try
hCur := LoadCursor(0, IDC_ARROW);
DrawIconEx(hDesktopDC,
30,
530,
hCur,
0,
0,
0,
0,
DI_DEFAULTSIZE or DI_IMAGE);
finally
ReleaseDC(0, hDesktopDC);
end;
end;

  
これを矢印本体だけを描画して,周囲を透明 (透過) したいと思うのですが,
どんな方法があるでしょうか ?
まず,フォームにマウスカーソルを描いて,そのリージョンをデスクトップに描画する.
というのが考えられますが,デスクトップに直接描画したいのです.
もし,アイディアや情報をお持ちの方がいましたら,是非お願いします.
一応,Windows 7 + Delphi XE VCL で動作可能なものが望みですが,
他の環境で,こうやれば,できるよ.という情報でも構いません.

えっとですね.この動作仕様なんですが.
実用性は,全く無視です.単なる興味の問題です.
でも,もしかしたら,将来役に立つかも知れません (ないか ?)

参考にならないかも知れないリンク
[Windows: DrowIconExで透過が出来ない。。。]
http://d.hatena.ne.jp/ken_2501jp/20130406/1365268503

Nov
メンバー
投稿数: 14
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 00:59 Mon

引用 Mr.XRAY on 2013/05/05 18:06 Sun
これを矢印本体だけを描画して,周囲を透明 (透過) したいと思うのですが,
どんな方法があるでしょうか ?

DI_NORMALにするだけかと思ったら、駄目なんですね…
フォーカスを描画するとちゃんと描画されるようですので、無駄な行を追加しました。
理由は聞かれても、未熟者ゆえ、分かりません。
変更箇所は下線部です。

procedure TForm1.Button1Click(Sender: TObject);
var
hDesktopDC : HDC;
hCur : HCURSOR;
rc: TRect;
begin

hDesktopDC := GetDC(0);
GetWindowRect(GetDeskTopWindow, rc);
rc.Inflate(1, 1); // 陰でこっそり
DrawFocusRect(hDesktopDC, rc);
DrawFocusRect(hDesktopDC, rc);
try
hCur := LoadCursor(0, IDC_ARROW);
DrawIconEx(hDesktopDC,
30,
530,
hCur,
0,
0,
0,
0,
DI_DEFAULTSIZE or DI_NORMAL); // 変更
finally
ReleaseDC(0, hDesktopDC);
end;
end;
Nov
メンバー
投稿数: 14
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 01:08 Mon

忘れてました。finally の後ろに追加しておいてください。

DestroyCursor(hCur);
DEKO
管理者
投稿数: 2690
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 02:06 Mon

では私はインチキな方法を。

procedure TForm1.Button1Click(Sender: TObject);
var
hDesktopDC: HDC;
BitMap: TBitmap;
bf: BLENDFUNCTION;
begin
hDesktopDC := GetDC(GetDesktopWindow);
BitMap := TBitmap.Create;
try
Bitmap.LoadFromFile('C:\aero_arrow.bmp');
with bf do
begin
BlendOp := AC_SRC_OVER;
BlendFlags := 0;
SourceConstantAlpha := $FF;
AlphaFormat := AC_SRC_ALPHA;
end;
Windows.AlphaBlend(hDesktopDC, 30, 530, 32, 32, Bitmap.Canvas.Handle, 0, 0, 32, 32, bf);
// Winapi.Windows.AlphaBlend(hDesktopDC, 30, 530, 32, 32, Bitmap.Canvas.Handle, 0, 0, 32, 32, bf); // XE2 or later
finally
Bitmap.Free;
ReleaseDC(GetDesktopWindow, hDesktopDC);
end;
end;

 
C:\aero_arrow.bmp は、C:\Windows\Cursors\aero_arrow.cur を 32bit Bitmap に変換したものです。

See Also:
[Alphablend API]
http://msdn.microsoft.com/ja-jp/library/cc428300.aspx

[BLENDFUNCTION 構造体]
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183393%28v=vs.85%29.aspx

Mr.XRAY
メンバー
投稿数: 192
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 07:02 Mon

わわっ,皆さんスミマセン.
こんなくだらないことにレスしていただきまして,早速やってみます.

Mr.XRAY
メンバー
投稿数: 192
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 07:54 Mon

ありがとうございます.動作報告です.

Nov さんの方のコードは,Inflate が Delphi XE2 以降のようでしたので,
DEKO さんのコードも両方,Delphi XE2 で確認しました.
DEKO さんの方は,aero_arrow_xl.cur を 32 ビットのビットマップに変換してテストしました.

コードは,そのままコピペして実行しました.ばっちりです.
でも,しかし,Nov さんのこんな簡単なコードで.
また,AlphaBlend という関数があるのをすっかり忘れていました.

う~む.まだまだ勉強不足を実感しました.
サンプルプログラム集の関係あるコードも,機会をみつけて追加または修正します.

で,嬉しいので画像も載せます.
質問の文章内のリンクのブログにも教えたいと思います.ご了承ください.

Nov
メンバー
投稿数: 14
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 12:30 Mon

Inflate が Delphi XE2 以降のようでしたので

いろいろ試しましたが、FocusRectの矩形範囲内が、正常にラスタオペレーションされるようなので、

rc := Rect(-1, -1, MAXINT, MAXINT);

でもOKなようです。
指定した矩形範囲の外側は、直前のFocusRectの背景が使われているような気がします。
(しつこい様ですが、動作原理が分かって書いているわけではありません。なぜこうなるのか、逆に教えてください~)

DEKO
管理者
投稿数: 2690
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 16:50 Mon

引用 Nov on 2013/05/06 12:30 Mon
指定した矩形範囲の外側は、直前のFocusRectの背景が使われているような気がします。

 
不思議な仕様 (?) ですよね。

procedure TForm1.Button1Click(Sender: TObject);
var
hDesktopDC: HDC;
hCur: HCURSOR;
rc: TRect;
begin
hDesktopDC := GetDC(0);
GetWindowRect(GetDeskTopWindow, rc);
InflateRect(rc, 1, 1); // 陰でこっそり
DrawFocusRect(hDesktopDC, rc);
try
hCur := LoadCursor(0, IDC_ARROW);
DrawIconEx(hDesktopDC,
30,
530,
hCur,
0,
0,
0,
0,
DI_DEFAULTSIZE or DI_NORMAL); // 変更
finally
DestroyCursor(hCur);
ReleaseDC(0, hDesktopDC);
end;
end;

 
補足 (蛇足) ですが TRect.Inflate を API で書き直すとこうなります。

See Also:
[InflateRect API]
http://msdn.microsoft.com/ja-jp/library/cc410418.aspx

Mr.XRAY
メンバー
投稿数: 192
Re: デスクトップにお絵かき (DelWiki)
on: 2013/05/06 21:58 Mon

>補足 (蛇足) ですが TRect.Inflate を API で書き直すとこうなります。

InflateRect ですね.了解しました.
しかし,何とも不思議な現象ですね.
DrawFocusRect の説明を読んでみると,≪XOR 演算子を使って枠を描画します≫
とか書いてあるので,このあたりも関係するのかも知れません.
枠線を XOR 演算するということは,当然その枠線内部の処理も伴います.
この関数の内部処理が分からないと,現象のこれ以上の追及は無理かも知れませんね.

[DrawFocusRect]
http://docwiki.embarcadero.com/Libraries/XE2/ja/Vcl.Graphics.TCanvas.DrawFocusRect
http://msdn.microsoft.com/ja-jp/library/cc428464.aspx

ページ: [1] 2
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.056 sec.