dポイントプレゼントキャンペーン実施中!

Excel2000 VBA で既存ツールの改造を行っています。

VBA内で画面を最大化、及びExcelのサイズ変更(最大化⇔標準化、最小化、消去)ボタンやメニューは消去しているのですが、最大化したExcel画面の上の枠(青色のタイトル欄)をダブルクリックすると、Excelの画面が標準化サイズに縮小してしまいます。
Excel画面の上の枠のダブルクリックでのサイズ変更をロックする方法をご存知の方、教えて頂けないでしょうか?
宜しくお願い致します。

A 回答 (5件)

GetWindowLong、SetWindowLong は


WindowsAPIで、Windows上の全ての
ウィンドウに共通するアーキテクチャを
変更します。
例えば、どのウィンドウにもクラス名、
スタイル、拡張スタイル、プロシージャが
あります。これらの情報を取得/変更
するのが上記APIです。Excelに限る話では
ありません。
DispalyFullScreen=Trueはこのスタイルの
CAPTION(BORDERとDLGFRAME)をOFFにする
だけです。これですとSYSMENUが残るので、
ダブルクリックや「元に戻す」が有効なままです。
実際にフルスクリーンになった画面の上部で
ダブルクリックすると元に戻ります。

なので、フルスクリーンにした直後に、スタイルの
SYSMENUをOFFにすればよいでしょう。
スタイルには他に可視、許可、最大化ボタン、
最小化ボタン、枠など様々なフラグがあります。
例えば可視はWS_VISIBLE=&H10000000です。
これをOFFにすると見えなくなります。
スタイルは32ビット中の上位16ビットですが、
下位16ビットは拡張スタイルです。これも上記の
APIで設定できます。索引は-20です。
どんなフラグがあるかはWS_xxx、WS_EX_xxを
ネットで調べれば分かると思います。
最初に示したC言語サンプルでもプロシージャの
変更にSetWindowLongを使っています。

VBAでAPIを使えると、マルチスレッド以外の
大抵のことがVBAでできるようになります。
FTPでファイルを転送したり、マルチプロセスで
100業務を5個ずつ同時処理するなど自在です。
    • good
    • 0
この回答へのお礼

何度も親切な回答ありがとうございます。
SetWindowLong関数を用いて試してみます。
画面の最大化以外にも「WS_xxx、WS_EX_xx」の種類を調べて、実際に動作させてみようと思います。

お礼日時:2012/01/27 19:50

昔使った手を思い出したので掲載します。


やはりAPIを使います。
Type RECT
  左 As Long
  上 As Long
  右 As Long
  下 As Long
End Type
Type WINDOWPLACEMENT
  バイト数 As Long
  フラグ As Long
  表示形式 As Long
  最小位置(1) As Long
  最大位置(1) As Long
  RECT As 四辺
End Type
Declare Function GetWindowPlacement Lib "USER32" _
  (ByVal ウィンドウ As Long, 情報 As WINDOWPLACEMENT) As Long
Declare Function SetWindowPlacement Lib "USER32" _
  (ByVal ウィンドウ As Long, 情報 As WINDOWPLACEMENT) As Long
Declare Function GetWindowRect Lib "USER32" _
  (ByVal ウィンドウ As Long, 情報 As RECT) As Long
Const WS_WS_THICKFRAME As Long = &H40000
'★画面を最大化した後に実行する
Sub サンプル()
Dim X As WINDOWPLACEMENT
Dim S As Long

'ウィンドウの枠を変更不能にする
S = GetWindowLong(Application.Hwnd, GWL_STYLE)
S = S And (Not WS_WS_THICKFRAME)
SetWindowLong Application.Hwnd, GWL_STYLE, S
'最大化した時の位置、サイズ情報を記録する
X.バイト数 = Len(X)
GetWindowPlacement Application.Hwnd, X
'最大化した時の四辺の位置を記録する
GetWindowRect Application.Hwnd, X.サイズ
'通常時の四辺の位置を設定する
SetWindowPlacement Application.Hwnd, X
End Sub

元のサイズに戻しても最大化の時のサイズに
近い大きさを保ちます。但し、画面は移動でき
ます。
    • good
    • 0
この回答へのお礼

サンプルプログラムのご教示ありがとうございます。
到底、私には思いつかない技ですね。
プログラムを見て(実際はコメントを見ながらですが)、「なるほど」と思います。
VBAやAPIの知識を身に付け、少しでも「nda23さん」に近づけたらと思います。
本当にありがとうございました。

お礼日時:2012/01/27 19:51

Excelのウィンドウに対するイベントは


殆ど解放されていませんので、VBAで
イベントを拾うことはできません。
究極的にはサブクラス化しかないの
ですが、タイトルバーを消し、「元に
戻す」をできなくするには以下のように
します。

Public Const GWL_STYLE As Long = -16
Public Const WS_CAPTION As Long = &HC00000
Public Const WS_SYSMENU As Long = &H80000
Public Declare Function GetWindowLong _
  Lib "user32" Alias "GetWindowLongA" _
  (ByVal ウィンドウ As Long, _
  ByVal 索引 As Long) As Long
Public Declare Function SetWindowLong _
  Lib "user32" Alias "SetWindowLongA" _
  (ByVal ウィンドウ As Long, _
  ByVal 索引 As Long, _
  ByVal 設定値 As Long) As Long

Sub サンプル()
Dim スタイル As Long
スタイル = GetWindowLong(Application.hwnd, GWL_STYLE)
スタイル = スタイル And (Not (WS_CAPTION Or WS_SYSMENU))
SetWindowLong Application.hwnd, GWL_STYLE, スタイル
End Sub

でも、画面がキレイじゃない気がするなぁ。
    • good
    • 0
この回答へのお礼

今回も親切なソース付きの回答、ありがとうございます。
タイトルバーを消すことは、「nak777rさん」に教えていただいた
「Application.DisplayFullScreen = True」で実現できたのですが、
「nda23さん」が回答下さっているSetWindowLong関数は、
「Application.DisplayFullScreen = True」とは結果が異なるのでしょうか?

ちなみに現在は、VBA起動時(Workbook_Open関数)に「Application.DisplayFullScreen = True」を行い、
VBA終了時(Workbook_BeforeClose関数)に「Application.DisplayFullScreen = False」を行っています。

何度も質問ばかりして申し訳ありません。ご存知でしたら教えて下さい。
宜しくお願い致します。

お礼日時:2012/01/26 22:31

Application.DisplayFullScreen = True



では駄目でしょうか?
    • good
    • 0
この回答へのお礼

回答、ありがとうございます。
「Excel画面の上の枠(青色のタイトル欄)をVBAで非表示にする。」
は「Application.DisplayFullScreen = True」で実現できました。

お礼日時:2012/01/26 22:15

C言語でDLLを作り、Excelのウィンドウ


プロシージャをフックしてある種の
メッセージを無効化します。
【Cプログラム】
static WNDPROC 旧プロシージャ = NULL;
static LRESULT WINAPI フック(
  HWND ウィンドウ,UINT メッセージ,
  WPARAM Wパラメータ,LPARAM Lパラメータ) {

  //タイトルバーのダブルクリックを無効化
  if ( メッセージ == WM_NCLBUTTONDBLCLK) return 0;
  //「元に戻す」を無効化
  if ( メッセージ == WM_SYSCOMMAND ) {
    WPARAM x = (Wパラメータ & 0x0000FFFF);
    if ( x == SC_RESTORE ) return 0;
  }
  //上記以外は以前のプロシージャに制御を渡す
  return CallWindowProc(旧プロシージャ,ウィンドウ,
       メッセージ,Wパラメータ,Lパラメータ);
}
void WINAPI WindowSetup(HWND ウィンドウ) {
  if ( 旧プロシージャ ) {
    //設定済みなら解除する
    SetWindowLong(ウィンドウ,GWL_WNDPROC,
                 (LONG)旧プロシージャ);
    旧プロシージャ = NULL;
  }
  else {
    //未設定ならフックする
    旧プロシージャ = (WNDPROC)GetWIndowLong(
                 ウィンドウ,GWL_WNDPROC);
    SetWindowLong(ウィンドウ,GWL_WNDPROC,フック);
  }
}
【VBA】
'DLLの定義
Declare Sub WindowSetup Lib "~" (ByVal ウィンドウ As Long)

Sub サンプル()
WindowSetup Application.hwnd 'フックする
End Sub


このプロシージャはトグルになっており、
呼び出しの度に設定と解除を交互に繰り返す。
フックしたら終了前に必ず解除する。
フックした後でVBAがリセットされるかExcelが
終了すると異常が発生する。
※VBAでフックプロシージャを作ると正しく動作
 しない。

Cでビルドする時は定義ファイルでエントリ名を
指定しないと、VBAから呼び出せません。
Cコンパイラが無い場合は機械語をバイト配列に
組み込んで、そのエントリを呼び出すという、
ちょっと危ない方法もあります。
その時のコードは長いので、必要ならご相談
ください。
    • good
    • 0
この回答へのお礼

親切な回答、ありがとうございます。
DLLを作成し、メッセージの無効化を行うという高度な技ですね。

ということは、ダブルクリックでのサイズ変更(元に戻す)をVBA内でロックすることは不可能ということでしょうか。
今回は、可能な限りVBA内の改造で対応したいと考えています。

邪道かもしれませんが、以下のどれかの方法で最大化表示を実現したいと思っています。
1.ダブルクリックでのサイズ変更後、VBA内で「元に戻す」イベントを検出できれば、最大化処理を行う。
  (ダブルクリック実行時、一瞬画面は小さくなるが、すぐに最大化表示に戻る。)
2.元に戻すサイズを最大化(最大化に近いサイズ)にVBA内で変更する。
3.Excel画面の上の枠(青色のタイトル欄)をVBAで非表示にする。

VBA初心者で、実現方法がわかっておりません。
ご存知でしたら教えて頂けないでしょうか。お手数掛けますが、宜しくお願い致します。
又、上記1~3以外にもVBA内の実現で、名案がありましたらご教示下さい。

お礼日時:2012/01/26 11:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!