SSブログ

トロPのVBAホビラボ Windows APIでのStringの使い方をみる [トロPのVBAホビラボ]

前回はString型変数のメモリーイメージを調べました。今回は、VBAからのWindows API使用において、String型の引数はどのような扱いを受けているか見ていきましょう。

まず、おなじみのHello World!を書いてみましょう。今回はMessageBox関数を使うことにします。

MessageBox関数のC言語ないしはC++言語での書式は次のようになっています。

MessageBox関数の書式(C言語またはC++言語)
int MessageBox(
  HWND hWnd,          // オーナーウィンドウのハンドル
  LPCTSTR lpText,     // メッセージボックス内のテキスト
  LPCTSTR lpCaption,  // メッセージボックスのタイトル
  UINT uType          // メッセージボックスのスタイル
);

MSDNの説明の下の方に「Unicode版とANSI版を実装」とありますので、実際のところは、MessageBoxAとMessageBoxWという2つの関数がエクスポートされているのでしょう。

インポートライブラリは「User32.lib」だそうですので、「user32.dll」というDLLでエクスポート
されていると予想されます。

日本語版のMSDNを読んだところでは、これらのことは実験してみるまで自信が持てないのですが、英語版のMSDNにははっきり同じ結果が記載されています。

ちなみに項目の部分を読むだけですので、英語版のMSDNを読むといっても英語力はほぼ不要です。

まだの方はこの機会に、英語版のMSDN「利用」も始めてはいかがでしょうか。

さて、本線に戻りましょう。

int、HWND、UINTは調べていくといずれも4バイトのデータ型です。VBAでは同じ4バイトの
Long型を利用するとシンプルに済みそうです。

LPCTSTRは「STR」とついていますので何やら文字列を表すことはわかりますが、そう考えるとVBAではString型かなと思うところです。

では、ANSI版の関数MessageBoxAを、String型の引数を値渡しして呼び出してみましょう。

サンプル
Private Declare PtrSafe Function WAPI_MessageBox Lib "user32" Alias "MessageBoxA" _
    (ByVal hWnd As Long, ByVal lpText As String, ByVal lpCaption As String, _
    ByVal uType As Long) As Long

Public Sub ShowHelloWorld()

    Debug.Print WAPI_MessageBox(0, "Hello World!", "ShowHelloWorld", 0)

End Sub
実行結果
MBHelloWorld.png
イミディエイトウィンドウ
1

どうやらうまくいったようです。

ここで、イミディエイトウィンドウを使って少し調べてみましょう。

イミディエイトウィンドウ
? LenB("Hello World!")
24

12文字の"Hello World!"は、24バイトだそうです。ということは、少し飛躍しますがどうやらUnicodeに対応したエンコーディング、もっというとUTF-16が使われているようです。

Unicode文字列のString型でANSI版の関数に渡してうまくいくのですから、非常に違和感があります。なぜUnicode版ではなくANSI版の関数を使ってうまくいくのでしょうか。

試しにUnicode版の関数を使ってみましょう。上のサンプルで、"MessageBoxA"の部分を"MessageBoxW"と変えるだけですのでプログラムは省略します。

実行結果
MBHelloWorlde.png

やはりアレレと言いたくなるような結果になりました。

邪推ですが、外部ライブラリーの関数にString型の引数を渡すとき、VBAではANSI文字列に変換することになっているのではないでしょうか。

このことを解明する代わりと言ってはなんですが、ここでは、何とかしてMessageBoxWをVBAから使う方法を考えてみたいと思います。

といっても実は、こちらの方がより直接的・基本的な呼び出し方です。

LPCTSTRは、簡単にいうと文字列へのポインターで、呼び出された方では引数のデータを
書き換えないものです。ポインターなのですから、VBAではLongPtrを当てればよいでしょう。

また、「TSTR」の部分は、ANSI版ならANSI文字列型、Unicode版ならUnicodeの文字列型であるワイド文字列型に置き換わるように定義されています。

つまり、実際にはデータ格納済みのワイド文字列の先頭アドレスを要求しているわけです。この先頭アドレスは、前回調査した通り、StrPtrで得られますから、解答は次のようになります。

サンプル
Private Declare PtrSafe Function WAPI_MessageBox Lib "user32" Alias "MessageBoxW" _
    (ByVal hWnd As Long, ByVal lpText As LongPtr, ByVal lpCaption As LongPtr, _
    ByVal uType As Long) As Long

Public Sub ShowHelloWorld()

    Dim l_TmpLng As Long

    Debug.Print WAPI_MessageBox _
        (0, StrPtr("Hello World!"), StrPtr("ShowHelloWorld"), 0)

End Sub

StrPtrを書く必要が生じるものの、形式的に変換して書けた気持ちよさがありますね。恐らくANSI全盛の自体に作られたプログラムへの配慮でこのような仕様になっているのでしょう。

ちなみに、勿論ANSI版もこの発想で利用することができます。

サンプル
Private Declare PtrSafe Function WAPI_MessageBox Lib "user32" Alias "MessageBoxA" _
    (ByVal hWnd As Long, ByVal lpText As LongPtr, ByVal lpCaption As LongPtr, _
    ByVal uType As Long) As Long

Public Sub ShowHelloWorld()

    Dim l_TmpLng As Long

    Debug.Print WAPI_MessageBox _
        (0, _
        StrPtr(StrConv("Hello World!", vbFromUnicode)), _
        StrPtr(StrConv("ShowHelloWorld", vbFromUnicode)), _
        0)

End Sub

もはや違和感を通り越してイヤ感ですね。でもまあ、頑なにレガシーホルダーをケアする姿勢として私は評価できると思います。

なお、本記事にて200記事となりました。ご愛読ありがとうございます。


広告
nice!(0)  コメント(24)  トラックバック(0) 

nice! 0

コメント 24

Kermit

私はこの記事を最新の技術や以前の技術と似ているという話題で完全に読んでいます。素晴らしい記事です。
by Kermit (2017-10-11 08:10) 

Doug

私の親戚はいつも私が自分の時間を殺していると言います
ここではネットで、私が毎日経験を積んでいることは分かっています
thes快適な記事やレビューを読んで。
by Doug (2017-10-21 23:33) 

Ezekiel

私たちはボランティアの集まりで、
私たちのコミュニティの新しいスキームです。あなたのサイトは私たちを提供
作業に役立つ情報を提供します。あなたは大変な仕事をしてくれて、私たちのグループ全体があなたに感謝しています。
by Ezekiel (2017-10-30 07:43) 

Shawna

素晴らしい、それは何のウェブサイトですか!このブログは貴重な事実を提供します
私たちに、それを維持してください。
by Shawna (2017-10-30 08:02) 

Rory

Ahaa、この記事に関するこの素晴らしい会話
このウェブサイトでは、私はそれをすべて読んだので、この時点で私もここでコメントしています。
by Rory (2017-10-30 08:03) 

Delphia

私は私の友人からこのウェブサイトを入手しました。
私はこのウェブサイトを訪問しており、この場所で非常に有益な記事やレビューを読んでいます。
by Delphia (2017-10-30 08:27) 

Adela

HowdyはあなたのサイトプラットフォームにWordpressを使用していますか?私はブログ世界には新しい
私は自分自身を作成し​​て作成しようとしています。コーディングの専門知識が必要ですか?
自分のブログ?どんな助けでも大歓迎です!
by Adela (2017-10-30 08:53) 

Earnestine

私が探していたものだけでうわー。検索でここに来た
プライベート用
by Earnestine (2017-10-30 09:15) 

Hai

驚くべき投稿をありがとう!私は本当にそれを読むことを楽しんだ、あなたは素晴らしいです
私はあなたのブログをブックマークして、間違いなく今から戻ってきます
に。私はあなたの偉大な仕事を続けることを奨励したい、素晴らしい
週末!
by Hai (2017-10-30 09:29) 

Libby

素晴らしい、非常に有益な置く。なぜ私が
この分野の反対の専門家は気付かない
この。あなたはあなたの文章を続けなければなりません。私は確信しています、
あなたは既に素晴らしい読者の基盤を持っています!
by Libby (2017-10-30 09:53) 

Clifford

このウェブページを訪問して、すべての同僚の意見を読むことはすばらしい
この記事に関しては、私も親しみを得たいと熱望しています。
by Clifford (2017-10-30 19:01) 

Dan

ウェブ上のトピックを見つけるのはとても簡単です
書籍と比較して、私はこの記事を
このウェブページ
by Dan (2017-10-30 19:52) 

Bonita

良い一日!私はちょうどこのポストであなたがここに持っている素晴らしい情報のための巨大な親指を与えたいと思う。

もうすぐあなたのウェブサイトに戻ってきます。
by Bonita (2017-11-04 22:16) 

Winona

ちょうどあなたに素早く頭を上げたいと思っていました。
あなたの記事のテキストは、Operaの画面に表示されていないようです。
私はこれがフォーマットの問題かブラウザの互換性と関係があるかどうかはわかりませんが、私は投稿すると思いました
あなたに知らせるために。デザインとスタイルは素晴らしいですね!
すぐに問題が解決されることを願っています。名声
by Winona (2017-11-04 23:27) 

Jesse

ここの素敵なブログ!さらにあなたのWebサイトの多くを
速い!あなたはどのようなホストですか?あなたのホスト上にあなたの関連ハイパーリンクを取得できますか?
私は自分のサイトがあなたのものと同じくらい速くロードされることを願っています
by Jesse (2017-11-04 23:37) 

Florine

あなたの考えを共有していただきありがとうございます。私は本当にあなたの努力に感謝し、私は待っています
あなたの次のポストはもう一度あなたに感謝します。
by Florine (2017-11-05 00:14) 

Denisha

非常に良い情報。私は偶然あなたのウェブサイトを横断しました(stumbleupon)。
私は後でそれを記した本を持っています!
by Denisha (2017-11-09 23:34) 

Hyman

素晴らしい投稿。私はいつもこのブログをチェックしていましたが、私は感心しています!
具体的に閉鎖段階に非常に役立つ情報:
)私はそのような情報を多く気にします。私はこの特定の情報を探していました
非常に長い時間。ありがとう、幸運。
by Hyman (2017-11-30 23:23) 

Joleen

私はここでいくつかの良いものを学びました。間違いなく再訪のためのブックマークの価格。
このような魅力的な有益なウェブサイトを作成するためにどのくらいの努力を払ったのでしょうか?
by Joleen (2017-12-07 00:38) 

Harris

それが私のものなのか、他の人があなたのウェブサイトに問題を抱えているのか分かりません。
あなたの投稿に書かれたテキストの一部が画面からはみ出しているようです。
誰か他の人がコメントして、私にこれが起こっているかどうか知らせてもらえますか?
これは前に起こったので、これは私のインターネットブラウザの問題かもしれません。
感謝します
by Harris (2017-12-12 22:44) 

Terry

あなたが寄付ボタンを持っていないのは残念です!私は間違いなく
この素晴らしいブログに寄付してください!私は今、私はブックマーキングのために解決し、あなたのRSSフィードを私のGoogleアカウントに追加するだろうと思う。
私はブランドの新しいアップデートを楽しみにして、このサイトを私と共有します
Facebookグループ。すぐに話す!
by Terry (2017-12-17 01:46) 

Kelli

私は本当にデザインとレイアウトを楽しんでいます
あなたのブログの。それは私がここに来て訪問するのをもっと楽しくする目にはとても簡単です
より頻繁に。あなたはあなたのテーマを作成するために開発者を雇いましたか?
代表作!
by Kelli (2018-02-20 01:46) 

Melba

印象的なシェア!私は、これを持っている友人にこれを転送しました。
これについて少しの宿題をしています。そして、彼は実際に
私は昼食を買った
彼...笑。だから私はこれをrewordすることができます....食事のためにあなたに感謝!
しかし、ええ、話す時間を費やすことはありがたい
あなたのブログにこの問題があります。
by Melba (2018-02-23 07:54) 

日本超人気のスーパーコピーブランド激安通販専門店

ブランドN級品ブランドコピー 代引

大人気なブランドの新品が割引中圧倒的な人気があるセリーヌ、シャネルやルイヴィトンなどのブランドコピーの大量な新品が発売していて、超低価格と最高品質最高がお勧めたいポイントです。今、購入すると割引があって、絶好なチャンスを掴んで、こちらへチェックしましょう。高級なブランドコピーの新品が入荷高級なクロエ、ブルガリやバーバリーなどのブランドコピーの新品が発売中で、いま色々な割引があって、高品質の商品を低価格で提供いたします。書類も豊富で、優れたデザインと実用性を兼ね備えた商品で、いつも好評を博します。}}}}}}
人気の売れ筋商品を多数取り揃えております。
全て激安特価でご提供.お願いします.
★100%品質保証!満足保障!リピーター率100%!
★商品数も大幅に増え、品質も大自信です。
★スタイルが多い、品質がよい、価格が低い!
★顧客は至上 誠実 信用。
★歓迎光臨
★送料無料(日本全国)
https://www.ginzajp.com/productall-4437.html

by 日本超人気のスーパーコピーブランド激安通販専門店 (2020-07-09 06:19) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。