欠落エクスポートを回避するには

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

欠落エクスポートを回避するには

#1 投稿記事 by yama »

SPIRITさんのActiveBasic講座のウィンドウを半透明にする(Win2000以上) をためさせていただきました。(いつも参考にさせていただいてます)
http://www.geocities.jp/skynet3113/data ... tml#Window

サンプル自体は問題なく成功したのですが、XPでコンパイルしたEXEを95、98環境で実行させたとき、透過の機能を使わないようにしたいのです。

Win2000以前のOSの時はスキップさせようと、Winのバージョン判定し、透過のコードの方はIFでスルーする様にできたのですが、

Declare Function SetLayeredWindowAttributes Lib "user32" (hwnd As Long,crKey As Long, bAlpha As Byte,dwFlags As Long) As Long

EXEを実行した時上記部分でプログラム開始エラーとなってしまいます。98・XP両方で使える様にするにはどのようにすればよいのでしょうか?

98SEでもエラーが出ないPCと、出るPCがあるのも謎です。
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

明示的リンクをすれば良いです

#2 投稿記事 by イグトランス »

Declareで宣言したDLL関数はプログラムの実行開始時にその関数が見つからないといけません。
SetLayeredWindowAttributesはWindows 2000以上にのみ存在する関数ですから,
Windows 98などではそれが存在せず実行が開始できないのです。

どうするかというと,明示的リンクをすることになります。
プログラムのはじめ(Createイベントなど)でLoadLibraryを行い,
GetProcAddressでSetLayeredWindowAttributesのアドレスを入手します。
そのアドレスは関数へのポインタの変数へ代入することでその関数を呼ぶことができます。
Windows 98などではGetProcAddressがNULLを返すので,それに気を付ければ良いだけです。

もちろんFreeLibraryを忘れてはいけません。
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

Re: 明示的リンクをすれば良いです

#3 投稿記事 by yama »

イグトランスさんこんにちは

> プログラムのはじめ(Createイベントなど)でLoadLibraryを行い,
> GetProcAddressでSetLayeredWindowAttributesのアドレスを入手します。
> そのアドレスは関数へのポインタの変数へ代入することでその関数を呼ぶことができます。
> Windows 98などではGetProcAddressがNULLを返すので,それに気を付ければ良いだけです。
>
> もちろんFreeLibraryを忘れてはいけません。

結構大変なんですね。LoadLibrayにて検索して試してみようと思います。ありがとうございました。
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

できました。

#4 投稿記事 by yama »

結果的にこのようにしたら動的リンクができました。まだ98にてのテストは行っていませんが、大丈夫だと思うんだけどなー
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#5 投稿記事 by イグトランス »

試しにWindows 98で実行してみましたが,落ちます。
Windows 98もuser32.dllはあります。しかし,SetLayeredWindowAttributesは無いのでGetProcAddressはNULLを返すからです。
つまりDamSetLayeredWindowAttributesがNULLかどうかを確かめるのも必要です。

また,これは私がうっかりしていたことですが,ウィンドウを使うプログラムにおいて,
user32.dllは常に読み込まれて(ロードされて)いると仮定してよいのです。
(CreateWindowなどウィンドウプログラミングに必須の関数がuser32.dllにあり,それらをDeclareして使っているので)

こういうときはLoadLibraryの代わりにGetModuleHandle("user32.dll")が使えます。
するとFreeLibraryをする必要はありません。
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

すばやい検証ありがとうございます。

#6 投稿記事 by yama »

わざわざ時間をとって試していただいてすいません。

今はuser32.dllが有るか無いかをみていて、98でもあるので×
user32.dllの中にSetLayeredWindowAttributes関数がアルカナイカ
を見るわけですね。

また試してみます。
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

#7 投稿記事 by yama »

MainWnd_Createに書いた以前のコードに追加して自宅の98で確認しました。
時間がたって読みかえしたときずいぶんまごつきそうです。たくさんコメントかいていますが、もっとすっきりした書き方があるのでしょうね。
動いて何ぼということでいつも自分をなぐさめています。
今回も希望の機能が実現できました、ありがとうございました。
返信する