tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルギザギザのない、なめらか直線と円を描きたいです。
記事No16661
投稿日: 2023/08/24(Thu) 14:52
投稿者マイメモリー
毎回このサイトでは貴重な資料を拝見し、お世話になっております。
さて、本タイトルにもありますように「ギザギザのない直線と円」をVisualBasic Ver6.0とGDI+を使って
描きたいと考えております。
そこで、本サイトより「GdiPius.bas」をダウンロード致しました。SmoothingModeを使えば良さそうなの
ですが、どのようにプログラムコードを記述すれば良いのか分かりません。
Public declare Function GripsetSmoothingMode〜なる関数も示されており、とても興味深いのですが、
どのようにこの関数を使えば「アンチエイリアス処理」が可能になるのか知りたいと思っております。
また、この関数を使うに当たって、何か注意点等がありましたら教えて頂きたく存じます。
よろしく、お願い致します。

[ツリー表示へ]
タイトルRe: ギザギザのない、なめらか直線と円を描きたいです。
記事No16662
投稿日: 2023/08/24(Thu) 21:41
投稿者魔界の仮面弁士
> そこで、本サイトより「GdiPius.bas」をダウンロード致しました。
どこにあったものでしょうか?
GdiPius.bas というのが
GdiPlus.bas のことだったとしても、出所が分かりませんでした。

自分の場合は、SDK を基にして Const や Declare を自前で書いてしまうタチゆえ
そのような .bas の存在自体把握していませんでした。

一応探してみたのですが、似たような名前の物が幾つか見つかったものの、
「本サイト」にあたる URL が何処か分かりませんでした。
ここのサイト (VB レスキュー) にありましたっけ?
https://github.com/peterennis/aegit/blob/master/aerc/src/basGDIPlus.bas
https://github.com/Planet-Source-Code/avery-use-gdi-aka-gdiplus-with-vb6-and-win98__1-37541/blob/master/GDIPlus%20API.bas
http://freesourcecode.net/vbprojects/17603/sourcecode/ModGDIPlus.bas


> SmoothingModeを使えば良さそうなのですが、
GDI+ で線を描画する時のアンチエイリアス処理であれば、そのとおりです。

.NET Framework の世界では、Graphics クラスの SmoothingMode プロパティを使い、
C++ のクラスでは、Graphics オブジェクトの SetSmoothingMode / GetSmoothingMode を使い、
GDI+ Flat API では、GdipSetSmoothingMode 関数 / GdipGetSmoothingMode 関数を使います。

ちなみに、文字を描画するときのアンチエイリアス処理ならば、TextRenderingHint です。
( GdipSetTextRenderingHint / GdipGetTextRenderingHint )

要件次第では PixelOffsetMode も併用すると良いかも知れません。
( GdipSetPixelOffsetMode / GdipGetPixelOffsetMode )


> どのようにプログラムコードを記述すれば良いのか分かりません。
> Public declare Function GripsetSmoothingMode〜なる関数も示されており、とても興味深いのですが、
GripsetSmoothingMode (グリップ セット スムージング モード) というのは
GdipSetSmoothingMode (ジーディーアイピー セット スムージング モード) のことですね。
スペルミスもそうですが、API 宣言では大文字小文字も区別されるので、正しく記述しましょう。


> どのようにこの関数を使えば「アンチエイリアス処理」が可能になるのか知りたいと思っております。
第一引数には、Graphics オブジェクトのハンドルを渡し、
第二引数には、下記の SmoothingMode 列挙定数を指定します。
この指定は、直線、曲線、および塗りつぶし領域の境界部に適用されます。

Public Enum SmoothingMode
  SmoothingModeInvalid      = -1& '(無効なモードであることを表します)
  SmoothingModeDefault      = 0&  'アンチエイリアス無しの既定の曲線スムージング
  SmoothingModeHighSpeed    = 1&  'アンチエイリアス無しの最高パフォーマンス
  SmoothingModeHighQuality  = 2&  'アンチエイリアス付きの最高品質
  SmoothingModeNone         = 3&  '曲線スムージングもアンチエイリアス処理も行いません
  SmoothingModeAntiAlias    = 4&  '8x4 ボックス フィルターを使用したアンチエイリアス処理を行います
#If GDIPVER >= &H110 Then
  SmoothingModeAntiAlias8x4 = SmoothingModeAntiAlias
  SmoothingModeAntiAlias8x8 = 8&  '8x8 ボックス フィルターを使用したアンチエイリアス処理を行います
#End If
End Enum

※ SmoothingModeAntiAlias8x8 の利用には、GDI+ version 1.1 以降が必要です。(Vista 以降)


詳細は、GDI+ Flat API ドキュメント(の Graphics オブジェクトの項) をご覧ください。
https://learn.microsoft.com/ja-jp/windows/win32/gdiplus/-gdiplus-flatapi-flat

関数定義は、Windows SDK の gdiplusflat.h で示されています。
SmoothingMode の定義は、gdiplusenums.h をお読みください。
Windows SDK をお持ちでない場合は、下記から最新版 [Windows 11 SDK (10.0.22621.0)] を入手できます。
https://developer.microsoft.com/ja-jp/windows/downloads/windows-sdk/

なお「ボックス フィルター」とは、長方形領域内のピクセルの平均を算出することによって
ピクセルの新しい値を計算するアンチエイリアス アルゴリズムです。(これが役に立つのは縮小時のみ)
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-emfplus/08ea5d19-dbd9-4056-9db3-424d8f47c3c1
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-emfplus/bbd10016-833c-4da5-ba4b-6c9ae93c67f2#gt_5ec85b39-64a4-4fae-8a36-366c39238fb9


> また、この関数を使うに当たって、何か注意点等がありましたら教えて頂きたく存じます。
今回提示した参考資料などを基にして VB6 に翻訳して実装できそうですか?
正直なところ、自力調査して実装できるだけの基礎力が無いのであれば、諦めた方が無難かと思います。
何しろ、GDI+ の Flat API は公式には unsupported ですし、ましてや今回は、
利用元が VB6 という古い開発環境な組み合わせですから。

不明点を具体的に挙げてもらえれば説明はしますし、必要であればサンプルを提示することもできますが、
流石に一から十まで教えるわけにはいかないので…どこまでできていて、何が分からないのかを
明確にしてみてください。

[ツリー表示へ]
タイトルRe^2: ギザギザのない、なめらか直線と円を描きたいです。
記事No16663
投稿日: 2023/08/25(Fri) 14:30
投稿者マイメモリー
魔界の仮面弁士 様、早速のご回答をありがとうございました。
GdiPlus.basの出所の件ですが、記事No.15598で紹介されているサイトにありました。
AntiAlias.zipをDLして解凍すると、以下の4つのファイルが含まれており、その中の
1つにGdiPlus.basがありました。

      AnitAlias.vbp
            AntiAlias.vbw
            form1.frm
            GdiPlus.bas

AnitAlias.vbpをクリックして起動し、VisualBaasic Ver6.0の画面が現れてF5キーを押すと

メイリオ、36Pt/Print

などのアンチエイリアス処理のかかった文字が表示されました。

GdiPlus.basがある標準モジュール内の記述を見ると Public Enum〜等の記述がたくさんなされており、
その中にSmoothingModeを見つけました。また、Form内にはGDI+を利用した記述がありました。
このForm内の記述を上手に利用できないものかと様々に試してみるのですが、なかなか思うような線や円
を描くことができません。やはりLine文、Circle文を適当に挿入するだけでは無理なのでしょうか?
相当に難しいのであれば今回は諦めたいと思いますが、魔界の仮面弁士 様の方でサンプルを提示していた
だけるのであればとてもありがたく思います。
いろいろな資料を紹介して頂いたにも関わらず、ご不便をおかけする話になりまして誠に申し訳ございません。
今回は、私にとってかなりハードルの高い内容になってしまいました。こんな私ではありますが、よろしく
お願い致します。

[ツリー表示へ]
タイトルRe^3: ギザギザのない、なめらか直線と円を描きたいです。
記事No16664
投稿日: 2023/08/25(Fri) 15:33
投稿者魔界の仮面弁士
> 魔界の仮面弁士 様、早速のご回答をありがとうございました。
> GdiPlus.basの出所の件ですが、記事No.15598で紹介されているサイトにありました。
これですか。
http://hanatyan.sakura.ne.jp/vb60bbs/wforum.cgi?no=15598&reno=15597&oya=15597&mode=msgview&page=210

だとすれば、そのコンテンツの所有権はこのサイトでは無いので、
『本サイトよりダウンロードした』と表現するのは語弊があるかと…。

記載されてた vb-user.net は私が管理しているドメインであり、
そこに含まれている GdiPlus.bas は私自身が書いたものです。(^^;

定義については、昨日 No.16662 でお答えした、 gdiplusflat.h などを
VB6 向けに翻訳しただけです。


> このForm内の記述を上手に利用できないものかと様々に試してみるのですが、なかなか思うような線や円
> を描くことができません。やはりLine文、Circle文を適当に挿入するだけでは無理なのでしょうか?
Line や Circle や Print や PSet や PaintPicture といったメソッドは、
GDI (ジーディーアイ: Graphic Device Interface) 系の API による実装であり、
GDI+ (ジーディーアイ・プラス) とはまったくの別物です。

GDI は、それこそ 16bit 版の Windows の時代から存在していましたが、
GDI+ は Windows XP で標準搭載されたものです。(Win98/98SE/NT4SP6/2000 にも導入可能)


たとえば VB6 では、円弧や扇形を描くために Circle メソッドを呼び出しますが、
これは内部的には、 GDI API の Ellipse 関数が呼び出されています。
https://www.vbforums.com/showthread.php?858443-RESOLVED-replace-Circle-method-with-API
https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/nf-wingdi-ellipse


一方、GDI+ でそれらを描く場合には、DrawEllipse や DrawArc や DrawPie を用います。
https://dobon.net/vb/dotnet/graphics/drawrectangle.html
これらを、GDI+ Flat API に置き換える場合は、
 GdipDrawArc 関数
 GdipDrawArcI 関数
 GdipDrawPie 関数
 GdipDrawPieI 関数
 GdipDrawEllipse 関数
 GdipDrawEllipseI 関数
などを使います。
末尾が I のものは整数座標系、I 無しは小数座標系です。

また、ベジエ曲線やカーディナルスプラインも扱えます。
https://dobon.net/vb/dotnet/graphics/drawcurve.html


> 今回は、私にとってかなりハードルの高い内容になってしまいました。
サンプルを書くにしても、範囲が広すぎて何を示せば良いのか…という状態です。


改めて、超えるべきハードルを並べておきます。

・"GDI+ Flat API" は、C++ ラッパーライブラリから内部的に呼ばれるためのものであり、
 C++ や VB6 からの直接利用を保証していませんし、サポートもされていません。
 https://learn.microsoft.com/ja-jp/windows/win32/gdiplus/-gdiplus-flatapi-flat

・GDI+ Flat API を使うのであれば、その前提となる GDI+ に関する知識が必須となります。
 まだ GDI+ に触れたことが無いのであれば、先に VB.NET / C# / C++ などといった、
 GDI+ 用のラッパーライブラリーでの呼び出し方を学んでおくべきです。

・GDI+ のオブジェクトの使い方が分かったら、先に紹介した資料群を用いて、
 それらを VB6 から呼び出せる Flat API の宣言へ、自力で書き換えていきます。
 そのためにも、Windows SDK の入手が必要になってきますし、
 C/C++ のヘッダーファイルを VB6 向けに翻訳できるだけの基礎知識も要求されます。

・API 宣言や定数については、第三者が作った *.bas ファイルで代用できるとしても、
 それらを組み合わせて呼び出していくには、どちらにしても GDI+ に関する知識が必要ですね。
 https://learn.microsoft.com/ja-jp/windows/win32/gdiplus/-gdiplus-about-gdi--about


ざっと検索してみたら、 Visual Basic 向けでは無い物の、
PowerBASIC 向けの GDI+ Flat API のリファレンスがありました。
そのまま直接使えるものでは無いにしても、参考にはなるかもしれません。
http://www.jose.it-berater.org/gdiplus/iframe/index.htm

[ツリー表示へ]
タイトルRe^4: ギザギザのない、なめらか直線と円を描きたいです。
記事No16665
投稿日: 2023/08/25(Fri) 17:23
投稿者マイメモリー
魔界の仮面弁士 様へ

このたびはGdi+に関しての様々なご教授をありがとうございました。
かなり奥の深い内容であること、十分に分かりました。
私なりにGdi+に関する書籍を探してみたいと思います。何か他にVisualBasic Ver6.0とGdi+を使った
プログラムコードがあれば、それらからも知識を深めていこうと思っています。
今は大きな壁に前を遮られた心境ですが、ゆっくり、ゆっくりと基礎知識を積み重ねていきますね。
重ね重ね、このたびは有り難うございました。

[ツリー表示へ]
タイトルRe^5: ギザギザのない、なめらか直線と円を描きたいです。
記事No16666
投稿日: 2023/09/06(Wed) 10:14
投稿者魔界の仮面弁士
追伸。

GDI+ を呼び出す場合、最初に GdiplusStartup を呼び出してやり、
使用後には GdiplusShutdown を呼び出す必要がありますが、
この処理は複数回呼び出してはいけません。メモリリークします!
https://social.msdn.microsoft.com/Forums/ja-JP/c2db5c2f-16ff-417a-9641-1d2f7da6060d/gdiplusstartup-gdiplusshutdown-?forum=windowssdksupportteamja

プログラムの開始時(または最初に GDI+ の機能を呼び出す際)に GdiplusStartup を一度だけ呼び出し、
アプリ終了まではその token を保持しておき、プログラム終了後に GdiplusShutdown を呼ぶようにします。


VB6 向けの描画処理サンプル(太極図を GDI 版 & GDI+ 版でそれぞれ描くもの)を
久しぶりに書こうとしたものの、Paint イベント内でうっかり GdiplusStartup / GdiplusShutdown を
毎回呼んでしまうという失態をおかしてしまった…。

[ツリー表示へ]
タイトルRe^6: ギザギザのない、なめらか直線と円を描きたいです。
記事No16667
投稿日: 2023/09/07(Thu) 00:30
投稿者マイメモリー
魔界の仮面弁士 様へ

VB6でGDI+を使うのは相当に難しいと思っている昨今です。
ネット上で時折調べてはいるのですが、C++用のサンプルはものすごく沢山掲載されているのに対して
VB6用は皆無に等しいようです。やはり、諦めるしかないのかも知れません。
私が持っている図形ソフトなどは、よ〜く観察して見るとマウスカーソルでカチッと押すまでは線がギザ
ギザしているのですが、確定すると滑らかな線に早変わりしていました。私の自作ソフトにもこの技が組
み込まれれば見栄えするのだが・・・と思っている今日この頃であります。
ありがとうございました。追加資料を。何かまた別の機会に使えればと思い、大切にとっておきますね。

[ツリー表示へ]