• ベストアンサー

VBAにGDI+を参照させる方法

VBAの参照設定でSystem.Drawing.dllクラスを参照設定させると、設定できませんと出ます。 VBAではグラフィック操作を行うことはできないのでしょうか。ユーザーフォームに数値目盛りを描きたいとおもっています。どなか分かる方ご教授願います。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#2です。 煩雑なので、API宣言はPublicにして標準モジュールに置く事にします。 C言語ならヘッダーファイルに持っている情報をVBAでは自前で宣言してやる必要がありますので、面倒くさいです。 Public Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type Public Type PICTDESC cbSizeofstruct As Long picType As Long hbitmap As Long hpal As Long unused_wmf_yExt As Long End Type Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Public Type POINTAPI x As Long y As Long End Type Public Type LOGPEN lopnStyle As Long lopnWidth As POINTAPI lopnColor As Long End Type Public Const PICTYPE_BITMAP = 1 Public Const SRCCOPY = &HCC0020 Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, _ ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _ ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long Public Declare Function CreateCompatibleBitmap Lib "gdi32" _ (ByVal hdc As Long, ByVal nWidth As Long, _ ByVal nHeight As Long) As Long Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long Public Declare Function CreatePenIndirect Lib "gdi32" (lpLogPen As LOGPEN) As Long Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Public Declare Function GetClientRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long Public Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long Public Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Public Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As Any) As Long Public Declare Function OleCreatePictureIndirect Lib "olepro32" _ (lpPictDesc As PICTDESC, riid As GUID, _ ByVal fOwn As Long, lplpvObj As Object) As Long Public Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hgdiobj As Long) As Long Public Declare Function WindowFromAccessibleObject Lib "oleacc.dll" _ (ByVal IAcessible As Object, ByRef hWnd As Long) As Long

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

昔作成したのをアレンジしてみました。 GDI+でなくて、GDIを使います。というか、WindowsAPIですが。 APIでUserFormに描画する場合、ウィンドウが隠れると描画したものが消えてしまうという問題があります。Windowsの再描画のメッセージをキャッチして、自前で再描画させる方法もありますが、VBAでは処理速度が追いつかない等課題があります。ここではPictureに変換して書き戻すことで、Pictureの再描画の機能を利用しています。コマンドボタン等もひっくるめて絵になってしまう訳ですが、少し試した限りでは問題なく動作する様です。 UserFormモジュールに記述します。APIの宣言は別途投稿します。 Private Sub UserForm_activate() Dim pic As StdPicture Dim rc As RECT Dim hwndForm As Long Dim hdcForm As Long Dim hdc As Long Dim hbmp As Long Dim hbmpOld As Long Dim hNewPen As Long Dim hOldPen As Long Dim NewPen As LOGPEN WindowFromAccessibleObject Me, hwndForm Me.Repaint GetClientRect hwndForm, rc hdcForm = GetDC(hwndForm) hdc = CreateCompatibleDC(hdcForm) hbmp = CreateCompatibleBitmap(hdcForm, rc.Right, rc.Bottom) hbmpOld = SelectObject(hdc, hbmp) 'UserFormのクライアント領域をメモリ上のビットマップに複写 BitBlt hdc, 0, 0, rc.Right, rc.Bottom, hdcForm, 0, 0, SRCCOPY ReleaseDC hwndForm, hdcForm 'メモリ上のビットマップに描画 NewPen.lopnColor = vbRed NewPen.lopnWidth.x = 10 hNewPen = CreatePenIndirect(NewPen) hOldPen = SelectObject(hdc, hNewPen) Call MoveToEx(hdc, 10, 10, Null) Call LineTo(hdc, 10, rc.Bottom - 10) Call LineTo(hdc, rc.Right - 10, rc.Bottom - 10) Call LineTo(hdc, rc.Right - 10, 10) Call LineTo(hdc, 10, 10) hNewPen = SelectObject(hdc, hOldPen) DeleteObject hNewPen ' SelectObject hdc, hbmpOld DeleteDC hdc Set pic = GetPictureObject(hbmp) If pic Is Nothing Then DeleteObject hbmp 'メモリ上のビットマップをPictureに変換してUserFormに設定 Set Me.Picture = pic ' Me.Repaint End Sub '==================================================== ' HBITMAPからPictureオブジェクトを作成する関数 Private Function GetPictureObject(ByVal hbmp As Long) As Object Dim iid As GUID Dim pd As PICTDESC If hbmp = 0 Then Exit Function With iid .Data1 = &H20400 .Data4(0) = &HC0 .Data4(7) = &H46 End With With pd .cbSizeofstruct = Len(pd) .picType = PICTYPE_BITMAP .hbitmap = hbmp End With OleCreatePictureIndirect pd, iid, 1, GetPictureObject End Function

参考URL:
http://homepage1.nifty.com/rucio/main/tyukyu/tyukyu6.htm
全文を見る
すると、全ての回答が全文表示されます。
回答No.1

System.Drawing.dll って .NET Framework 用のライブラリでしょ。 VBA 用じゃありません。 使ったことはないですが、こんなのがあるようです。 http://www.f3.dion.ne.jp/~element/msaccess/AcTipsFrmGdiClass.html

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VBAをDLL化する方法を教えてください。

    Excelの中で、UserFormを使用し、グラフを操作するプログラムをVBAで作成しています。 そこで、VBAのソースを見られないようにするために、全てDLL化してだれにでも配信できるようにしたいと考えていますが、どのようにすれば、DLLにできるのかわかりません。 VBAのパスワードだけでは弱いので、DLL化する方法がありましたら、どなたかその方法をご教授願います。

  • VBAで呼び出したVBのDLLのデバッグ方法

    VB2010で、COM相互運用機能を使って作成したDLLを VBAから呼び出すことはできるのですが この状態でこのDLLをデバッグすることはできないでしょうか。 本来ならば、DLLをデバッグするテストプログラムを VB2010のVB.NETのWindowsフォームアプリケーションか ConsoleApplication1で作成して、 同じソリューションの中に DLLとテストプログラムのプロジェクトを配置して 参照の追加でDLLを参照設定して 両者をデバッグをすると思われますが、 テストプログラムを作るのがかなり大変なのと、 今回作成したDLLは、元々はVBAの中のひとつのプロシージャ―で、 事情があって、このプロシージャ―だけをVBのDLLにしたものです。 このプロシージャ―は元々はVBAの中で正しく動作していたものです。 VBに書き直した時に何らかの不具合が起きていると思われます。 テストプログラムを作らずに、既存のVBAから呼び出して、 DLLの部分の動作だけを(できればVB2010で)デバッグできないでしょうか。 よろしくお願いします。 (WindowsXP SP3 , Excel2003のVBA , Visual Studio 2010)

  • VBA 参照設定について

    Windows7 Access 2013です。 以下サイトを参考にして、VBAに貼り付けたところ ”ユーザー定義型は定義されていません” というコンパイルエラーが出ました。 http://gdipluscode.sakura.ne.jp/gdip/resize_save_jpeg.html 引っかかっている部分は Optional ByVal InterpolationMode As InterpolationMode の部分のようです。 参照設定で、不足があるのではないかと思うのですが、 ネット検索をかけても、参照設定に関するヒントが、見つかりませんでした。 GDI+を使ったほかのプログラムでは、参照設定に引っかからなかったので 今回どうすればよいか、わかりにくく困っております。 解決方法について、ご教授願います。

  • C# 別プロジェクトのフォームを参照する方法

    同じソリューションに複数のプロジェクトが存在しています。 その中のあるプロジェクト[Aプロジェクト]から別のプロジェクト[Bプロジェクト]に存在する フォームクラスを参照したいのですが、参照できません。 Bプロジェクト内に存在するクラスは参照できるのですが、フォームだけが参照できない状態です。 Bプロジェクトのフォームは、次のように宣言されています。 public partial class frmEdit : Form { ・・・・・・・・・ } もう1つのpartialクラスはfrmEdit.Designnerクラスに存在します。 どうすれば、参照できるようになるでしょうか? ご存知の方、ご教授お願い致します。

  • Access VBA 参照設定とは・・?

    Access初心者です。2003を使用しています。 ライブラリの参照設定(この表現でわかるでしょうか?)で参照するライブラリを増やし、モジュールを作成しました。このモジュールを含むツールは問題なく私のPCでは動いていましたが、ファイルサーバに投入し他のPCで実行させると、「・・・参照する切断された参照が含まれています。」とエラーがでてしまいます。 エラーを一旦閉じ、参照設定を見ると「(非参照)・・・・」にチェックが入っていました。このチェックを外すと問題なく動きます。チェックを外す作業を他の人にやってもらったので、ライブラリ名までわかりませんが、ツール作成時に「Microsoft ActiveX Data Object 2.1 Library」を参照可能にしました。 以下が初心者な質問ですがご教授いただきたい部分です。 ライブラリの参照設定は、インストールされているAccessに設定されるのでしょうか?それとも、作成したファイル毎の設定になるのでしょうか?前述の場合でしたら、ツールを配付した先で設定を変更してもらわねばなりません。後述でしたらモジュールをインポートした際に参照設定を変更しなければなりません。 また、参照設定の変更はVBAを用いて変更可能でしょうか?(フォームボタンから参照のON・OFF) へたくそな文章で伝わり難いとは思いますが、どなたかご教授ねがいます。

  • vbaの参照とtlb

    某社のFXトレーディング用api(dll)を使って為替トレーディングをしています。 vbaからの自動発注ですがxpの時は動いたのですが、server 2003にすると「該当のdllが見つからない」とエラーが出てエクセルが落ちてしまいます。 vbaの参照設定はxpの時と同じtlbファイルのパスになっています。 tlbファイルの中身はわかりませんが、レジストリに正しくパスが登録されていないか、server 2003固有の問題かいずれかと考えています。 どなたか心あたりのある方ご教示いただけるとありがたいです。 某社のテクニカルサポートに聞いてはいますがapiについてのサポートは限定的と思われ、回答はあっても来週以降になると思っています。 よろしくお願いします。

  • VBScript Regular Expressionsの参照設定

    Excel VBAで VBScript Regular Expressions を使おうと思います。 Excelによって参照設定ができているものもあるので参考にしているの ですが、そのファイルをみると c:\windows\system32\vbscript.dll\3 とかなっていて、そのまま採用してもファイルがないといってはねられ ます。 どのファイルにどのように参照設定すればいいのでしょうか?

  • DLLから他のプロジェクト変数の参照方法???

    C#でWindowsフォームのアプリケーションを作りました 構成は親のフォームのプログラムFormMain.csと5ケの子供プログラムFormSub1~5.csです データの受渡しは親プログラムの中に class CommonData { static public bool BoolData = true; static public int IntData = 1; static public string StringData = "冬が来ました"; } を作り、子供プログラムの中で if (CommonData.BoolData == false) ......... int j = CommonData.IntData; CommonData.StringData = "きっと春も来るでしょう"; などとやっておりました ところが今回事情があり、Windowsフォームのアプリケーションのプロジェクトとは別プロジェクトとして.NET C++でDLLを作らなくてはならなくなりました サンプル等を参照して何とかDLLを作り動かしましたが、DLLの中で上述のCommonData.BoolDataを参照しなくてはなりません デバックではDLLの中でCommonData.BoolDataに変わる固定値を臨時に設定してロジックを検証しました ところが本番ではWindowsフォームのアプリケーションのFormMain.csの中に規定されたCommonData.BoolDataを参照しなくてはなりません DLL側でどのようにすれば良いのでしょうか? なおCommonData.BoolDataのtrue、falseは時々刻々変化しますので、DLLが起動される度に最新の状態を参照したいのです

  • エクセル VBA ユーザーフォームで検索したいのですが

    つい昨日触り始めた大初心者です。。 エクセルシートにて 数値を記した列と、詳細を記した列があります。 ユーザーフォームにて textboxに数値を入力し、ボタンをクリックすると 検索をして、ユーザーフォーム内のlabelに詳細が表示される、といったvbaを書いているのですが、どうにもうまくいきません。 また、textboxに検索範囲にない数値が入力されたときには Labelに「なし」と表示させたいのですが、 エラーが出てしまい、その処理もやはりうまく出来ません。 どなたかご教授いただけますでしょうか。

  • ACCESSでVBAを使って・・・

    ACCESS VBAを使って、ユーザの専用フォームを開くようにしたいです。 具体的には、MDBのなかにユーザA/B/Cそれぞれの専用フォームを作成します。 ※表示する内容は項目は一緒ですが、その人個人のデータのみになります。 例えばユーザAに対するメッセージであるとか。秘匿性の高いものです。 MDBにアクセスする際、ユーザA/B/CにそれぞれID、PWを設定し、 ユーザAのID/PW→ユーザAのフォームが開く (以下同様にユーザBやユーザCもそのように) というようなことをしたいのですが、どのようにすれば実現可能なのか、教えていただけますでしょうか。 あるいはもっといい方法があればご教授願います。