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

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

C# と VB.NET の入門サイト

Re[2]: アクティブ化させないウィンドウ


(過去ログ 122 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■72850 / inTopicNo.1)  アクティブ化させないウィンドウ
  
□投稿者/ pod (10回)-(2014/07/25(Fri) 18:13:48)

分類:[C#] 

VS 2013 C#でスクリーンキーボードのようなものを作る際、クリックしてもキーボード側にフォーカスを移さないために、
WS_EX_NOACTIVATE を使ってアクティブ化を防ぎました。

private const int WS_EX_NOACTIVATE = 0x8000000;
protected override CreateParams CreateParams
{
	get
	{
		CreateParams p = base.CreateParams;
		if (!base.DesignMode)
		{
			p.ExStyle = p.ExStyle | (WS_EX_NOACTIVATE);
		}
		return p;
	}
}

そこまでは良かったのですが、フォームのドラッグ中やリサイズ中はウィンドウの位置やサイズが変化せず、ドロップ時(マウスアップ時)にだけ状態が変化します。

移動に関してはこちら(http://ccnet.dip.jp/wiki/index.php?CSharpMemo)のサンプルを元に組み込めたのですが、
ウィンドウのリサイズを正常に表示するにはどうすればいいのでしょうか?

引用返信 編集キー/
■72870 / inTopicNo.2)  Re[1]: アクティブ化させないウィンドウ
□投稿者/ 魔界の仮面弁士 (59回)-(2014/07/29(Tue) 17:06:53)
No72850 (pod さん) に返信
> そこまでは良かったのですが、フォームのドラッグ中やリサイズ中はウィンドウの位置やサイズが変化せず、
> ドロップ時(マウスアップ時)にだけ状態が変化します。

マウス操作ではなく、キーボードでのリサイズ動作は問題ないようですね。

(1)フォーム左上のアイコンを右クリックしてシステムメニューを表示
(2)[サイズ変更(S)]を選択
(3)矢印キーを押して方向を決定。上部ドラッグ相当なら↑。左部ドラッグ相当なら←。右下部なら→↓。
(4)さらに続けて、矢印キーを押し続けてリサイズする。
(5)リサイズの確定は Enter キー、キャンセルは Esc キー。



> ウィンドウのリサイズを正常に表示するにはどうすればいいのでしょうか?

SPY++ で拾ってみたところ、WS_EX_NOACTIVATE が付与されている状態だと、
WM_SIZING が SendMessage されているにも拘らず、マウス操作では
Form.Resize イベントが発火していない状態でした。


そこで試しに、WM_SIZING が通知されたときに、SetBoundsCore メソッドを
呼び出すようにしてみたところ、当方環境ではそれっぽく動きました。

なお SetBoundsCore の最後の引数は、All でも None でも
変化が見られませんでした。(何故だろう?)


using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
 public partial class Form1 : Form
 {
  public Form1()
  {
   InitializeComponent();
  }

  private const int WS_EX_NOACTIVATE = 0x8000000;
  protected override CreateParams CreateParams
  {
   get
   {
    CreateParams p = base.CreateParams;
    if (!base.DesignMode)
    {
     p.ExStyle = p.ExStyle | (WS_EX_NOACTIVATE);
    }
    return p;
   }
  }

  protected override void WndProc(ref Message m)
  {
   const int WM_SIZING = 0x214;
   const int WM_MOVING = 0x216;
   if (m.Msg == WM_SIZING || m.Msg == WM_MOVING)
   {
    Rectangle rect = Rectangle.FromLTRB(
      Marshal.ReadInt32(m.LParam, 0x0),
      Marshal.ReadInt32(m.LParam, 0x4),
      Marshal.ReadInt32(m.LParam, 0x8),
      Marshal.ReadInt32(m.LParam, 0xC));
    listBox1.Items.Insert(0, rect);
    base.SetBoundsCore(rect.X, rect.Y, rect.Width, rect.Height, BoundsSpecified.All);
   }
   else
   {
    base.WndProc(ref m);
   }
  }
 }
}
引用返信 編集キー/
■72877 / inTopicNo.3)  Re[2]: アクティブ化させないウィンドウ
□投稿者/ pod (11回)-(2014/07/30(Wed) 10:51:04)
No72870 (魔界の仮面弁士 さん) に返信

> SPY++ で拾ってみたところ、WS_EX_NOACTIVATE が付与されている状態だと、
> WM_SIZING が SendMessage されているにも拘らず、マウス操作では
> Form.Resize イベントが発火していない状態でした。
>
> そこで試しに、WM_SIZING が通知されたときに、SetBoundsCore メソッドを
> 呼び出すようにしてみたところ、当方環境ではそれっぽく動きました。

WS_EX_NOACTIVATEを使うと自前でメッセージを受け取らないといけないのですね。
ウィンドウメッセージには詳しくなかったので助かりました。
頂いたソースはこちらの環境でも問題なく動作しています。
ありがとうございます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -