- PR -

Messengerのような画面制御について

投稿者投稿内容
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-06-06 17:06
れいさん、回答ありがとうございます。


MainMenuコントロールの存在を知りませんでした。。。
MainMenuを使うことで思ったような動作をできそうだと思ったのですが、MainMenuクラスには
 ・Visible
が存在しませんでした。

タイトルバーを非表示にするには、やはりいったんDisposeして、再度表示する時にnewしなければならないでしょうか?
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-06-06 17:23
自己レスですいません。

> ・Visible
>が存在しませんでした。

フォームの
 ・Menu
にMainMenuをセットしなければ表示されないことがわかりました。

 表示する時
  ・This.Menu = mainMenu; // MainMenuクラスを設定
 表示しない時
  ・This.Menu = null;

上記で、表示/非表示は制御できました m(__)m
ただ、相変わらず画面がすごくちらついてしいます。。。


引き続き、いろいろ試してみます。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-06-06 23:51
LayeredWindowよりSetWindowRgnのほうがよさそうです。

コード:

Public Property ClientRectangleOnly() As Boolean
Get
Return Me.Region IsNot Nothing
End Get
Set(ByVal value As Boolean)
If value = Me.ClientRectangleOnly Then Exit Property
If Me.Region Is Nothing Then
Dim r As Rectangle
r.X = Me.PointToScreen(Me.ClientRectangle.Location).X - Me.Left
r.Y = Me.PointToScreen(Me.ClientRectangle.Location).Y - Me.Top
r.Width = Me.ClientRectangle.Width
r.Height = Me.ClientRectangle.Height
Me.Region = New Region(r)
Else
Me.Region = Nothing
End If
End Set
End Property

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
If Me.ClientRectangleOnly Then
Me.ClientRectangleOnly = False
Else
Me.ClientRectangleOnly = True
End If
End Sub



これで再描画はおきません。
縁がないときはサイズ変更できないとか、
xボタンがないとか、
その辺なんとかしないといけませんが。


[ メッセージ編集済み 編集者: れい 編集日時 2007-06-07 00:10 ]
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-06-07 01:58
引用:

LayeredWindowよりSetWindowRgnのほうがよさそうです。



Form.Region では駄目です?
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-06-07 02:56
引用:

渋木宏明(ひどり)さんの書き込み (2007-06-07 01:58) より:
引用:

LayeredWindowよりSetWindowRgnのほうがよさそうです。


Form.Region では駄目です?




投稿したコードではControl.Region使ってますよ。

Control.Regionだと再描画されてしまいますが、
SetWindowRgnだと再描画を1回防ぐことができるのでその分得ですが、
そのためにアンマネージ使うのもめんどくさいので
Regionプロパティでいいんじゃないでしょうか。

試してみましたがちらつきはどっちも見えませんでした。
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-06-09 13:07
れいさん、渋木宏明(ひどり)さん回答ありがとうございます。
返答遅れて申し訳ありませんでした m(__)m


れいさんが提示してくれたソースで実際に確認してみたところ、切替時のちらつきはほぼ皆無となりました。
同時にメニューバーも非表示にしてくれるので、この動きは非常に助かります。


Form.Regionというプロパティは今まで使ったことないので、提示いいただいたソースでなぜちらつかなくなったのか今後のために調べてみます。


とても助かりました。
ありがとうございました。
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-06-09 14:43
たぶたびの質問で申し訳ありません。


提示していただいた方法では画面にちらつきがないので、この方法で実装しようかと思っていたのですが、フォーム移動は座標値を取得することでできたのですが、
 ・画面サイズ変更
のロジックが、
 ・this.FormBorderStyle = FormBorderStyle.None;
でタイトルバーを表示/非表示制御していた時のロジックだと異常な動きをするようになってしまいました。
おそらくフォームの制御方法を変えたからだと思いますが、今の動きが把握できてなくて。。。

↓ ↓ (長くなるので、横方向の処理のみ抜粋) ↓
// ------------------
// フォームサイズ取得
// ------------------
int   size    = SystemInformation.FrameBorderSize.Width;
int   rightPos  = this.ClientRectangle.Width - size;
Point  p      = e.Location;

// ----------------------------------
// フォームサイズ変更処理中でない場合
// ----------------------------------
if (サイズ変更処理中) ←マウスUpイベントで処理を解除しています。
{
  // ------------------------------
  // カーソル位置で表示カーソル変更
  // ------------------------------
  if (p.X <= size)
  {
    this.Cursor   = Cursors.SizeWE;
    isRightBound  = false;
  }
  else if (rightPos <= p.X)
  {
    this.Cursor   = Cursors.SizeWE;
    isRightBound  = true;
  }
  else
  {
    this.Cursor   = Cursors.Default;
    isRightBound  = false;
  }
}
else
{
  // ------------------
  // 標準カーソルの以外
  // ------------------
  if (this.Cursor != Cursors.Default)
  {
    p = PointToScreen(e.Location);
    Rectangle rect = this.Bounds;

    // ----------
    // 右辺選択時
    // ----------
    if (isRightBound)
    {
      rect.Width = e.Location.X;
    }
    else
    {
      rect.X   = p.X;
      rect.Width -= e.Location.X;
    }
    this.Bounds = rect;
  }
}
↑ ↑ ↑
上記の場合、まずフォームの外枠(左・下・右)が表示されてしまいます。。。
なんとなくですが、フォームのサイズ自体が変わらずに可視範囲だけ狭まるような動きになっているみたいです。(フォーム端を判別する処理に入らなくなります。)



今デバッグしながら調査しているのですが、もしスマートなサイズ変更方法があればアドバイスいただきたいと思い、書き込みました。


わかる方いたら、ご指導願います。
よろしくお願いします。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-06-09 19:46

Windowsアプリは16bitの時代からの歴史の上になりたってますので、
こうしたい場合はこうする、
というような鉄則がたくさんあります。

一見で実現できそうで、実はうまくいかない、
みたいな場合は、違う簡単な実現方法がある場合が多々あります。

簡単な実現方法がない場合は、絶対に無理だったり。

extreamさんのコードのどこがうまくいかないかは試してないのでわかりませんが、
MouseDownやUpのイベントで移動やリサイズを行っても、
まともにうごきません。

#昔散々がんばって無理だったので、見たくもない・・・

サイズ変更は以下のようなコードを用いるのが簡単です。
私はForm系のアプリはVBなので、VBのコードですが。

コード:
    Private Const WM_NCHITTEST As Integer = &H84
    Private Const HTERROR = (-2)
    Private Const HTTRANSPARENT = (-1)
    Private Const HTNOWHERE = 0
    Private Const HTCLIENT = 1
    Private Const HTCAPTION = 2
    Private Const HTSYSMENU = 3
    Private Const HTGROWBOX = 4
    Private Const HTSIZE = HTGROWBOX
    Private Const HTMENU = 5
    Private Const HTHSCROLL = 6
    Private Const HTVSCROLL = 7
    Private Const HTMINBUTTON = 8
    Private Const HTMAXBUTTON = 9
    Private Const HTLEFT = 10
    Private Const HTRIGHT = 11
    Private Const HTTOP = 12
    Private Const HTTOPLEFT = 13
    Private Const HTTOPRIGHT = 14
    Private Const HTBOTTOM = 15
    Private Const HTBOTTOMLEFT = 16
    Private Const HTBOTTOMRIGHT = 17
    Private Const HTBORDER = 18
    Private Const HTREDUCE = HTMINBUTTON
    Private Const HTZOOM = HTMAXBUTTON
    Private Const HTSIZEFIRST = HTLEFT
    Private Const HTSIZELAST = HTBOTTOMRIGHT


    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case WM_NCHITTEST
                Dim p As Point
                p = Me.PointToClient(New Point(m.LParam.ToInt32 Mod 65536, m.LParam.ToInt32 \ 65536))

                If p.X > Me.ClientRectangle.Right Then Exit Select
                If p.X < Me.ClientRectangle.Left Then Exit Select
                If p.Y < Me.ClientRectangle.Top Then Exit Select
                If p.Y > Me.ClientRectangle.Bottom Then Exit Select

                If p.X < Me.ClientRectangle.Left + 5 Then
                    If p.Y < Me.ClientRectangle.Top + 5 Then
                        m.Result = HTTOPLEFT
                        Exit Sub
                    End If
                    If p.Y > Me.ClientRectangle.Bottom - 5 Then
                        m.Result = HTBOTTOMLEFT
                        Exit Sub
                    End If
                    m.Result = HTLEFT
                    Exit Sub
                End If
                If p.X > Me.ClientRectangle.Right - 5 Then
                    If p.Y < Me.ClientRectangle.Top + 5 Then
                        m.Result = HTTOPRIGHT
                        Exit Sub
                    End If
                    If p.Y > Me.ClientRectangle.Bottom - 5 Then
                        m.Result = HTBOTTOMRIGHT
                        Exit Sub
                    End If
                    m.Result = HTRIGHT
                    Exit Sub
                End If
                If p.Y < Me.ClientRectangle.Top + 5 Then
                    m.Result = HTTOP
                    Exit Sub
                End If
                If p.Y > Me.ClientRectangle.Bottom - 5 Then
                    m.Result = HTBOTTOM
                    Exit Sub
                End If
        End Select
        MyBase.WndProc(m)
    End Sub



どういう意味のコードかは、説明めんどくさいので
自分で調べてください。

あとアドバイスがひとつ。
フォームの移動にはHTCAPTIONを使うといいですよ。



スキルアップ/キャリアアップ(JOB@IT)