
No.7
- 回答日時:
ん~ おかしいですね …
当方は WinXP SP2 + Office2003の環境ですが
一点修正を
コード側でEnableMenuItemの最後の引数のMF_DISABLEは MF_DISABLEDの間違いでした m(__)m
すいません。
FindWindow("ThunderDFrame", "UserForm1")のところで"UserForm1"の名前を変えたので閉じるボタンが有効になっていたようです。そこを変更するのを忘れていました。
これで最小化ボタン有効、閉じるボタン無効に成功しました。
本当は分からないことがいっぱいあるのでお聞きしたいことがたくさんあるのですが、ここまで教えてもらっていただいて、さらにお聞きするのは大変申し訳ないので別の機会にします。
また、インターネットで自分でも調べられることは調べるようにしたいと思いました。
本当にありがとうございました。
No.6
- 回答日時:
ごめんなさい m(__)m
DeleteMenuではうまくいかないようです
いろいろ実験していたので誤った情報を書き込んだようです
EnableMenuItemを使えばできるようです
標準モジュールに
Public Declare Function EnableMenuItem Lib "user32" _
(ByVal hMenu As Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long
Public Const MF_DISABLED = &H2&
を追加します
Initializeイベントの DeleteMenuをEnableMenuItemに置き換えます
EnableMenuItem hSysMenu, SC_CLOSE, MF_BYCOMMAND or MF_DISABLE
といった具合です
No.5
- 回答日時:
> では Integer ではなく Long ではないでしょうか
そのとおりです m(__)m
いろいろ回答していたので間違えました
Ano3の補足への回答ですが
DeleteMenuの第2引数が MF_BUCOMMANDになっていますが
これは MF_BYCOMMANDにしないとだめですね
こういった単純なスペルミスを防ぐためにも『変数宣言の強制』を設定しておいたほうが良いでしょう
VBEの画面で ツール > オプションの変数タブ
『変数の宣言を強制する』のチェックをつけておきます
既存のVBAコードについては
コードの先頭で
Option Explicit
といった1行を追加しておきます
このようにしておけば 宣言されていない変数(定数)は使用できなくなりますので タイプミスによるバグはほとんど回避が可能になります
ただ似たような変数名の打ち間違いまでは面倒見てくれませんので・・・
たとえば
dim Hen1, Hen2
hen1 = 1
' 本来 hen1を判断するところを Hen2とタイプした
if Hen2 = 1 then
Hen2 = -1
' Hen3は宣言されていないのでチェックされる
Hen3 = Hen2 * 2
end if
この回答への補足
回答ありがとうございます。
なるほど。変数の宣言を強制した方が間違いが酸くなるんですね。勉強になります。
「MF_BYCOMMAND」に変更したのですがやはり、閉じるボタンが有効のままのようです。
「MF_BYCOMMAND」の値が「0」なのですがこれが原因なのでしょうか?
大変お手数ですがよろしくお願いします。
No.4
- 回答日時:
横レス失礼します。
。> Public Declare Function GetSystemMenu Lib "user32" Alias "GetSystemMenuA" _
> (ByVal hWnd As String, _
> ByVal bRevert As Boolean) As Long
API の宣言文(API に渡す引数の型を含めて)は、API に関する知識が
深まるまで勝手に変えず、API ビューアや WEB などで紹介されている
とおり、そのままコピペして使いましょう。
# これらの情報が絶対に間違っていないとは限りませんが...
Alias は意味もわからず付けてはダメです。また、GetSystemMenu の
第一引数 hWnd の型が String 型になってますが、Long 型の誤りかと。
参考URL:WinAPI Database for VB Programmer
http://www.winapi-database.com/
Declare Function GetSystemMenu Lib "user32.dll" ( _
ByVal hwnd As Long, _
ByVal bRevert As Long) As Long
Declare Function DeleteMenu Lib "user32.dll" ( _
ByVal hMenu As Long, _
ByVal nPosition As Long, _
ByVal wFlags As Long) As Long
なお、#3 ご回答ですが、VB.Net 用のものではないかと思われます。VBA
では Integer ではなく Long ではないでしょうか。
No.3
- 回答日時:
Declare宣言の関数名の最後にAをつけるのは ANSI/Unicodeの両方のAPIが存在する場合にどちらを使うのかを明確にするためです
FindWindowの参考URLの最後のほうに
『Unicode:Windows NT/2000 は Unicode 版と ANSI 版を実装』と明記されている場合に Aliasで指定します
GetSystemMenuはANSI/Unicodeの区別はありませんので
Declare Function GetSystemMenu Lib "user32.dll" _
(ByVal hWnd as Integer, ByVal bRevert as Integer) as Integer
といった具合の宣言で良いと思います
この回答への補足
なるほど。
オーバーフローしてしまったのでLongに変えて作ってみました。
まだ分からないところがたくさんあるのですが、以下のように作ったところ、最小化ボタンは表示されたのですが「×」が使える状態なのですがどこが間違ってるのでしょうか?
標準モジュール
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar Lib "user32" _
(ByVal hWnd As Long) As Long
Public Declare Function GetSystemMenu Lib "user32.dll" _
(ByVal hWnd As Long, ByVal bRevert As Long) As Long
Public Declare Function DeleteMenu Lib "user32" _
(ByVal hMenu As Long, ByVal uPosition As Long, ByVal uFlags As Long) As Long
Public Const GWL_STYLE = (-16) 'ウィンドウスタイルを取得
Public Const WS_MINIMIZEBOX = &H20000 '最小化ボタン
Dim hSysMenu As Long
Public Const MF_BYCOMMAND = &H0&
Public Const SC_CLOSE = &HF060&
Initializeプロシージャ
Private Sub UserForm_Initialize()
Dim fRet As Long
Dim hWnd As Long
Dim fStyle As Long
UserForm1.Show vbModeless
hWnd = FindWindow("ThunderDFrame", "UserForm1")
fStyle = GetWindowLong(hWnd, GWL_STYLE)
fStyle = (fStyle Or WS_THICKFRAME Or WS_MINIMIZEBOX)
fRet = SetWindowLong(hWnd, GWL_STYLE, fStyle)
hSysMenu = GetSystemMenu(hWnd, 0)
DeleteMenu hSysMenu, MF_BUCOMMAND, SC_CLOSE
fRet = DrawMenuBar(hWnd)
End Sub
度々すいません。
No.2
- 回答日時:
ん~ インターネットがあるのですから調べてみましたか?
MicrosoftのMSDNサイトやWinAPIを開設したサイトはたくさんありますよ
『疑問部分を全て説明しろ』と言うのは無理があるのです
最初のほうの Declare文はWinAPIをVBで使えるようにする宣言です
FindWindowはどのような引数をとるのかを調べてみると
ウィンドウクラス名とウィンドウのタイトルの2つが必要だと解説されているはずです
http://msdn.microsoft.com/library/ja/default.asp …
これで取得したハンドルを使ってどのウィンドウに対する処理をするのかをWindowsに指示するわけです
『ThunderDFrame』はウィンドウクラス名です
『UserForm1』はユーザーフォームのCaptionプロパティに設定した文字列です
次のGetWindowLongですが タイトルバーに表示するタイトル名や最小化、最大化、閉じるのボタンなどのウィンドウの外観を変更するのに現在の設定を知る必要があるために使うAPIです
http://msdn.microsoft.com/library/ja/jpwinui/htm …
GetWidowLongには引数nIndexに与えるデータによりさまざまなデータを取得可能なのです
今回は ウィンドウの外観なので GWL_STYLEを与えます
ここで取得したデータを使って希望するスタイルにするための演算を行います
fStyle = fStyle Or WS_MINIMIZEBOX
とします
もしも最大化ボタンが有効になっているのであれば そのスタイルを消去しないといけませんのでその場合は
fSyle = fStyle And ( Not WS_MAXIMIZEBOX )
といった具合にします
今度は外観を変更するためにWindowsに依頼するAPIを使う必要があります
これが SetWidowLongになります
http://msdn.microsoft.com/library/ja/jpwinui/htm …
SetWindowLong/GetWindowLongは最初のSetとGetが違いと Getがデータを返すので引数は2つ Setはデータを設定するので3つの引数といった違いがあります
この2つが対になっていることが理解できるでしょうか
その参照URLコードには閉じるボタンの無効化は無いようです
閉じるボタンは ウィンドウの左肩にあるアイコンをクリックすると出る『移動』『サイズ変更』『最小化』『最大化』『閉じる』といったメニュを操作する事になります
これをするには
宣言区に以下の3行を追加します
Dim hSysMenu as Long
Const MF_BYCOMMAND = &H0&
Const SC_CLOSE = &HF060&
DrawMenuBarを呼び出す前に以下の2行を追加します
hSysMenu = GetSystemMenu( hWnd, 0 )
DeleteMenu hSysMenu, MF_BUCOMMAND, SC_CLOSE
といった具合に使います
http://msdn.microsoft.com/library/ja/jpwinui/htm …
http://msdn.microsoft.com/library/ja/jpwinui/htm …
ここまでやってからDrawMenuBarを呼び出して変更を反映させます
http://msdn.microsoft.com/library/ja/jpwinui/htm …
この回答への補足
回答ありがとうございます。
プログラムにredfox63さんの言うとおりに追加したのですが、「エントリ GetSystemMenuAがDLLファイルuser32内に見つかりません」というエラーが出てしまったのですがこれはWinAPIをVBで使えるようにする宣言が間違ってしまったのでしょうか?以下の通りです。
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar Lib "user32" _
(ByVal hWnd As Long) As Long
Public Declare Function GetSystemMenu Lib "user32" Alias "GetSystemMenuA" _
(ByVal hWnd As String, _
ByVal bRevert As Boolean) As Long
Public Declare Function DeleteMenu Lib "user32" Alias "DeleteMenuA" _
(ByVal hMenu As Long, _
ByVal uPosition As Long, _
ByVal uFlags As Long) As Long
新たに「GetSystemMenu」と「DeleteMenu」を追加したのですが、 「Public Declare Function DeleteMenu Lib "user32"」まではいいのですが、 その後ろに「Alias "DeleteMenuA"」をつけるのかつけないのか分かりません。データ型は調べたので合ってると思いますが。
よろしくお願いします。
No.1
- 回答日時:
何処まで理解できていて 何が理解できていないのかを投稿しましょう
WinAPIの使い方をすべて説明するのは困難ですよ
『X』の非表示自体は無理です、無効状態になら出来ますが ・・・
WinAPIで操作するにはまずウィンドウハンドルを取得する必要があります ... FindWindow
次に 最小化、最大化、閉じるボタンの表示、非表示の設定をするにはウィンドウスタイルを変更するAPIを使います ... GetWindowLong/SetWindowLong
最小化、最大化は単独で表示、非表示の切り替えが可能です
閉じるは最小化、最大化、閉じるの3個セットで表示、非表示の切り替えになります
閉じるの無効化をするためにはそのウィンドウのシステムメニューを操作する必要があります ... GetSystemMenu/DeleteMenu/DrawMenuBar
この回答への補足
回答ありがとうございます。
参考URLからコピーしたものなんですが、まず最初に、
標準モジュール
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar Lib "user32" _
(ByVal hWnd As Long) As Long
この部分が何をしているのか分かりません。
それから、
標準モジュール
Public Const GWL_STYLE = (-16) 'ウィンドウスタイルを取得
Public Const WS_THICKFRAME = &H40000 'ウィンドウのサイズ変更
Public Const WS_MINIMIZEBOX = &H20000 '最小化ボタン
Public Const WS_MAXIMIZEBOX = &H10000 '最大化ボタン
この部分は恐らく「ウィンドウスタイルを取得」「最小化ボタン」が必要だとは分かります。あとの「ウィンドウのサイズ変更」「最大化ボタン」はこの場合は使用しないので必要ないと思います。
redfox63さんのおっしゃる「ウィンドウハンドルを取得する必要がある」というのは、
UserForm_Initializeプロシージャ
Dim fRet As Long
Dim hWnd As Long
Dim fStyle As Long
UserForm1.Show vbModeless 'ユーザーフォームを表示する
hWnd = FindWindow("ThunderDFrame", "UserForm1") 'ユーザーフォームのハンドルを取得する
fStyle = GetWindowLong(hWnd, GWL_STYLE) 'ウィンドウに関する情報を取得する
fStyle = (fStyle Or WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX) 'Min,Maxメニューボタンを付加する
fRet = SetWindowLong(hWnd, GWL_STYLE, fStyle) 'ユーザーフォームに追加したボタンを設定する
fRet = DrawMenuBar(hWnd) 'ユーザーフォームのメニューバー外枠を再描画する
「hWnd = FindWindow("ThunderDFrame", "UserForm1")」この部分でしょうか?
一番上の「UserForm1.Show vbModeless 」はいいとして、まず、
「"ThunderDFrame"」の意味が分かりません。それと「"UserForm1"」はオブジェクト名でしょうか?
>次に 最小化、最大化、閉じるボタンの表示、非表示の設定をするにはウィンドウスタイルを変更するAPIを使います ...
これは、「fStyle = GetWindowLong(hWnd, GWL_STYLE)」この部分でしょうか?ここでも何をしているのか分かりません。
>閉じるの無効化をするためにはそのウィンドウのシステムメニューを操作する必要があります
これは、どこの部分を指すのでしょうか?
「fStyle = (fStyle Or WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX) 」この部分は説明の通りなので「Or WS_MINIMIZEBOX」のみにすればいいというのは分かるんですが。
「fRet = SetWindowLong(hWnd, GWL_STYLE, fStyle)」この部分は全く分かりません。ただ、説明があるのでこの設定は絶対必要だというぐらいです。
「fRet = DrawMenuBar(hWnd)」ここも上記と同じです。
ほとんど分からないのですがすいませんが回答お願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(コンピューター・テクノロジー) PC利用中に勝手に起動する窓を消し去る方法を教えて下さい。 1 2023/05/08 16:48
- Access(アクセス) Access 登録ボタンからサブフォームの更新 1 2022/07/22 10:23
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- Visual Basic(VBA) VBAで早押しゲームを作りたい 4 2022/05/12 13:46
- その他(データベース) Accessフォームからパラメーターで表示したレコードを指定のExcelのセルへ転送する方法について 2 2022/08/22 18:04
- 教えて!goo 質問をして回答者さんにお礼文を書こうとしても、お礼のカウントを押すボタンだけは表示されて、それ以外の 1 2022/07/26 10:19
- 企画・マーケティング ウェブ広告の無意味な「×」ボタンは規約や消費者保護関連の法律の違反には当たらないですか? 画面上にデ 2 2023/06/18 19:21
- Word(ワード) Word のマクロについての質問です。 ボタンを押すと登録したブックマーク先にジャンプする機能(リン 3 2023/08/16 12:17
- その他(動画サービス) Tver アンケートに回答しても視聴できない(何度もアンケート画面が開く) 1 2023/01/13 21:47
- その他(Microsoft Office) windows10で作業を終了する際の「保存しますか はい いいえ」を表示させずに自動で保存する方法 6 2023/03/15 11:29
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
勝手にウィンドウが開いて止ま...
-
メニューバーの高さの取得方法
-
スクロールバーについて
-
他アプリのアクティブな子ウイ...
-
隠れたウィンドウの画面をキャ...
-
ゲームでは結局どっちが良いの?
-
ラジオボタンの初期指定
-
SetWindowPosで、移動可能のフ...
-
フリーのデータ消去ソフト「DES...
-
EXCEL VBA WindowsAPIの文字列...
-
MFC ダイアログ上のID取得につ...
-
2重起動の防止方法
-
ExcelのBOOKが消えた!
-
エクセル;新しいウインドウを開く
-
作成したウインドウのサイズを...
-
他のアプリケーションの終了処理
-
Console.WriteLine で表示されない
-
グラフを別ウィンドウで立ち上...
-
Excel2010-ファイルが開かない...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
Vba LongPtrについて教えてくだ...
-
勝手にウィンドウが開いて止ま...
-
ラジオボタンの初期指定
-
ゲームでは結局どっちが良いの?
-
検索の画面がでなくなってしま...
-
Excelの上下を固定したい
-
「&HFFFF」「&H1A」とは?
-
ExcelのBOOKが消えた!
-
エクセルで1行目から3行目が消...
-
[VBA] UserForm を Excel の W...
-
【VB2008】 マウス操作の一時的...
-
VBA .Value=.Value ?
-
作成したウインドウのサイズを...
-
DellノートPC購入で悩んでいま...
-
UWSCで特定のChromeのタブをア...
-
Alt+P,Alt+NをPostmessageで送...
-
隠れたウィンドウの画面をキャ...
-
Console.WriteLine で表示されない
おすすめ情報