C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.73348 の関連記事表示

<< 0 >>
■73348  フォーム最大化のキャンセル方法
□投稿者/ ビール呑み -(2014/09/15(Mon) 20:52:53)

    分類:[VB.NET/VB2005 以降] 

    2014/09/15(Mon) 21:00:46 編集(投稿者)

    web上のリソースを参考にvb.netプログラムの勉強をVS2010で始めたところでございます。
    (.NETバージョン:指定なしだがとりあえず4.0)

    次のような要件でウィンドウプログラムを作成し、目論見通りうまく動作しました。

    ・タイトルバーは表示しない(FormBorderStyle=none)
    ・最大化/最小化ボタンは不要(MaximizeBox=False, MinimizeBox=False)
    ・フォームの移動は、フォーム上の任意の位置をドラッグ&ドロップしておこなう。
    (以下のコードを記述)

    <System.Security.Permissions.SecurityPermission( _
    System.Security.Permissions.SecurityAction.LinkDemand, _
    Flags:=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)> _
    Protected Overrides Sub WndProc(ByRef m As Message)
    MyBase.WndProc(m)

    Const WM_NCHITTEST As Integer = &H84
    Const HTCLIENT As Integer = 1
    Const HTCAPTION As Integer = 2

    If m.Msg = WM_NCHITTEST And m.Result.ToInt32() = HTCLIENT Then
    m.Result = New IntPtr(HTCAPTION)
    End If
    End Sub

    ところが、この場合フォーム上の任意の位置をダブルクリックすると、フォームが最大化表示されてしまいます。

    WndProcに渡されるメッセージを一通り確認しましたが、「フォーム最大化」を
    単独で意味すると思われるものは見当たらず、またWM_SYSCOMMANDや
    WM_NCLBUTTONDBLCLKが渡される前に既に最大化されてしまうようです。

    ダブルクリックした場合には特定の処理を実行し、なおかつ最大化はキャンセル
    したいのですが、フォーム最大化の命令を捕捉してキャンセルするといった処理は
    難しいのでしょうか?

    有識者の方のご意見を参考にさせていただければと思います。よろしくお願い
    いたします。m(_ _)m
親記事 /過去ログ123より / 関連記事表示
削除チェック/

■73349  Re[1]: フォーム最大化のキャンセル方法
□投稿者/ 魔界の仮面弁士 -(2014/09/15(Mon) 23:55:03)
    No73348 (ビール呑み さん) に返信
    > web上のリソースを参考にvb.netプログラムの勉強をVS2010で始めたところでございます。
    And ではなく AndAlso を…というのは些末な話として:


    > ダブルクリックした場合には特定の処理を実行し、なおかつ最大化はキャンセル
    > したいのですが、フォーム最大化の命令を捕捉してキャンセルするといった処理は
    > 難しいのでしょうか?

    HTCLIENT のままにしておけば、そもそも通常通り DoubleClick イベントが発生します。
    HTCAPTION として扱ってしまっているが故に、話を難しくしてしまっているように思えます。


    > ダブルクリックすると、フォームが最大化表示されてしまいます。
    これを止めるだけならば、
     Protected Overrides Sub WndProc(ByRef m As Message)
      If m.Msg = &H24 Then 'WM_GETMINMAXINFO
       Dim rect As Rectangle = Me.DesktopBounds
       Marshal.WriteInt32(m.LParam, 8, rect.Width)
       Marshal.WriteInt32(m.LParam, 12, rect.Height)
       Marshal.WriteInt32(m.LParam, 16, rect.Left)
       Marshal.WriteInt32(m.LParam, 20, rect.Top)
       Marshal.WriteInt32(m.LParam, 24, SystemInformation.MinWindowTrackSize.Width)
       Marshal.WriteInt32(m.LParam, 28, SystemInformation.MinWindowTrackSize.Height)
       Marshal.WriteInt32(m.LParam, 32, SystemInformation.MaxWindowTrackSize.Width)
       Marshal.WriteInt32(m.LParam, 36, SystemInformation.MaxWindowTrackSize.Height)
       m.Result = IntPtr.Zero
    などという方法もありますが、「ダブルクリックされた時の処理」を
    残したいのであれば、そもそも、HTCAPTION への変換を止めた方が良いでしょう。



    WndProc のオーバーライドを行わず、移動処理のみを実装してみました。


    Public Class Form1
      Private Sub Form1_DoubleClick(sender As Object, e As EventArgs) Handles Me.DoubleClick
        MsgBox("Double Clicked!") 'ダブルクリック時に処理させたい内容
      End Sub

      Private mouseDownPoint As Point? = Nothing 'ドラッグ開始座標
      Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
        If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
          mouseDownPoint = e.Location
        End If
      End Sub

      Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
        If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
          mouseDownPoint = Nothing 'ドラッグ終了
        End If
      End Sub

      Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
        If mouseDownPoint.HasValue Then
          'ドラッグで座標移動
          Dim pos As Point = Me.Location
          pos.Offset(e.Location - mouseDownPoint.Value)
          Me.Location = pos
        End If
      End Sub
    End Class
記事No.73348 のレス /過去ログ123より / 関連記事表示
削除チェック/

■73356  Re[2]: フォーム最大化のキャンセル方法
□投稿者/ ビール呑み -(2014/09/16(Tue) 19:30:53)
    No73349 (魔界の仮面弁士 さん) に返信

    迅速なご返信、ありがとうございます。またこちらからの返信が遅くなり、申し訳ありません。

    > HTCAPTION として扱ってしまっているが故に、話を難しくしてしまっているように思えます。

    仰る通りだと思います。

    ただ、ウィンドウの移動という低レベルな処理のために複数のイベントプロシージャを
    記述するというのが可読性・汎用性の点でいかがなものかという思いもあり、
    WndProcの中でメッセージを処理して対応するというアイデア(別に私のアイデアという
    わけではないですが…)が捨てきれずに悶々としております。

    お示しいただいた
    >  Protected Overrides Sub WndProc(ByRef m As Message)
    >   If m.Msg = &H24 Then 'WM_GETMINMAXINFO
    >    Dim rect As Rectangle = Me.DesktopBounds
    >    Marshal.WriteInt32(m.LParam, 8, rect.Width)
    >    Marshal.WriteInt32(m.LParam, 12, rect.Height)
    >    Marshal.WriteInt32(m.LParam, 16, rect.Left)
    >    Marshal.WriteInt32(m.LParam, 20, rect.Top)
    >    Marshal.WriteInt32(m.LParam, 24, SystemInformation.MinWindowTrackSize.Width)
    >    Marshal.WriteInt32(m.LParam, 28, SystemInformation.MinWindowTrackSize.Height)
    >    Marshal.WriteInt32(m.LParam, 32, SystemInformation.MaxWindowTrackSize.Width)
    >    Marshal.WriteInt32(m.LParam, 36, SystemInformation.MaxWindowTrackSize.Height)
    >    m.Result = IntPtr.Zero
    という記述は、「サイズ変更されそうになったらサイズを設定し返す」というアプローチかと
    思いますが、もっとダイレクトに「最大化を禁止」「最大化をキャンセル」といった方法論は
    ないものでしょうか?

    (「あるに違いない」という思い込みだけで3連休を棒に振っているので、「んなものは無い」と
    ひとこと言っていただければ踏ん切りもつくのですが…)

    >>web上のリソースを参考にvb.netプログラムの勉強をVS2010で始めたところでございます。
    > And ではなく AndAlso を…というのは些末な話として:

    ?????
    すみません、わからないので解説いただけると幸いです。

記事No.73348 のレス /過去ログ123より / 関連記事表示
削除チェック/

■73357  Re[3]: フォーム最大化のキャンセル方法
□投稿者/ ビール呑み -(2014/09/16(Tue) 19:54:40)
    No73356 (ビール呑み さん) に返信

    > >>web上のリソースを参考にvb.netプログラムの勉強をVS2010で始めたところでございます。
    >>And ではなく AndAlso を…というのは些末な話として:
    >
    > ?????
    > すみません、わからないので解説いただけると幸いです。
    >

    あ、「If m.Msg = WM_NCHITTEST And m.Result.ToInt32() = HTCLIENT Then」
    のところのことでしょうか?
記事No.73348 のレス /過去ログ123より / 関連記事表示
削除チェック/

■73358  Re[4]: フォーム最大化のキャンセル方法
□投稿者/ Hongliang -(2014/09/16(Tue) 21:05:24)
    FormBorderStyle.Noneの場合、MaximizeBoxおよびMinimizeBoxの設定は無視されますが、その結果WS_MAXIMIZEBOXフラグが立ったままになって最大化ができてしまう、ということのようですね。
    // Win+↑でも最大化できるのでダブルクリックさせなくさせられれば良いというわけでもない。

    CreateParamsをオーバーライドして、StyleからWS_MAXIMIZEBOX(&H10000)ビットを落としてやれば最大化できなくなります。
    Const WS_MAXIMIZEBOX As Integer = &H10000
    Dim p As CreateParams = MyBase.CreateParams
    p.Style = p.Style And (Not WS_MAXIMIZEBOX)
    Return p
記事No.73348 のレス /過去ログ123より / 関連記事表示
削除チェック/

■73360  Re[5]: フォーム最大化のキャンセル方法
□投稿者/ ビール呑み -(2014/09/17(Wed) 00:31:58)
    No73358 (Hongliang さん) に返信


    動きましたぁ!!!


    もとい…


    Hongliangさんにご指示いただいた記述を追加したところ、ダブルクリックしても
    ピクリとも動きませんでしたぁ!!!

    (動かないプログラムがこんなに嬉しいなんて…)

    うーん、まだまだ知らない世界がいっぱいあるんですね。

    後は、魔界の仮面弁士さんにご指摘いただいているように、
    「ダブルクリックされた時の処理」を復活させてやる必要がありますね。
    これについてはもうしばらく試行錯誤してみます。

    魔界の仮面弁士さん、Hongliangさん、ありがとうございました。
    またお世話になると思いますが、よろしくお願いいたします。
    m(_ _)m
記事No.73348 のレス / END /過去ログ123より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -