2012-01-04 3 views
0

사용자가 winform을 이동하지 못하도록하고 싶습니다. winform의 위치를 ​​잠 그거나 고정시키는 방법은 무엇입니까? 그래서, 그들이 무엇을 하든지, 그것은 움직일 수 없습니다. win32의 경우 Windows 용 고정 옵션이 있다고 생각합니다. 이 옵션을 설정하면 이동중인 창 개요 만 표시되지만 실제 창은 원래 위치에 그대로 남아 있습니다. 나는 winform과 비슷한 일을하려고 노력하고있다. winform의 위치를 ​​잠 그거나 고정하는 방법은 무엇입니까?

편집

: 여기 이는 Win32에서 위치 변경 윈도우 메시지를 캡처하는 절차입니다 :

//Frozen is a user-defined boolean variable 
procedure TVIewFrm.WMPosChanging(var Msg: TMessage); 
var 
    wp:PWINDOWPOS; 
begin 
    if Frozen then 
    begin 
    wp := PWINDOWPOS(Msg.lParam); 
    wp^.flags := wp^.flags or SWP_NOMOVE; 
    end; 
    inherited; 
end; 

작업 절차 및 그 난의 WinForm와 함께 할 노력하고 있습니다 것입니다. 지금까지 당신은 모두 제가 찾고있는 솔루션이 아닌 주위에 작업을 게시했습니다.

+0

최대화 된 창은? 메뉴 막대가없고 드래그 가능한 모서리가없는 창? –

+0

WinForm의'WndProc'과 폼 윈도우의 드래그 이벤트를 무시할 수 있습니까? –

+0

@MrLister 최대화 될 수 있지만 메뉴 막대와 드래그 가능한 가장자리가 없습니다. – ThN

답변

0

여러분 중 일부는 가까이 왔지만, 저에게는 효과가 없었습니다. 귀하의 답변은 다소 어려움을 겪었습니다. 나는 솔직한 해결책을 찾고 있었다.

문제점을 파악했습니다. 내 솔루션은 완벽하게 작동하지만 winform의 윤곽을 그리거나 끌어 오지 않습니다. 이를 달성하기 위해 LarsTech와 비슷한 코드를 구현해야 할 것입니다.

//declared within a form class under protected 
method WndProc(var m:Message); override; 

//and is defined as follows. 
method MainForm.WndProc(var m: Message); 
const WM_NCLBUTTONDOWN = 161; 
const WM_SYSCOMMAND = 274; 
const HTCAPTION = 2; 
const SC_MOVE = 61456; 
begin 
    if ((m.Msg = WM_SYSCOMMAND) and (m.WParam.ToInt32 = SC_MOVE)) then 
    begin 
     exit; 
    end; 

    if ((m.Msg = WM_NCLBUTTONDOWN) and (m.WParam.ToInt32 = HTCAPTION)) then 
    begin 
     exit; 
    end; 
    inherited WndProc(var m); 
end; 

가 귀하의 답변에 대한 여러분 모두 감사합니다 :

여기 내 작업 코드입니다.

0

양식의 이동 이벤트에서 원하는 위치로 다시 위치를 설정하면됩니다.

+0

글쎄, 나는 사용자가 winform을 전혀 움직일 수 없도록하고 싶지 않다. 이동하려고해도 잠기거나 고정되어야합니다. 그러나 창을 끌려고하면 winform의 윤곽을 볼 수 있어야합니다.마우스를 올리거나 내 보내면 외곽선이 사라지지만 winform은 여전히 ​​원래 위치에 있어야합니다. – ThN

3

이 시도 :

Public Class UnmovableForm 

    Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs) 
     '' Remove the Move command from the system menu so the window becomes unmovable 
     Call RemoveMenu(GetSystemMenu(Me.Handle, False), SC_MOVE, MF_BYCOMMAND) 
     MyBase.OnHandleCreated(e) 
    End Sub 

    Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As IntPtr, ByVal nPosition As Integer, ByVal wFlags As Integer) As Integer 
    Private Declare Function GetSystemMenu Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal bRevert As Boolean) As IntPtr 
    Private Const MF_DISABLED As Integer = 2 
    Private Const MF_BYCOMMAND As Integer = 0 
    Private Const SC_MOVE As Integer = &HF010 
End Class 

희망이 당신의 문제를 해결합니다. 사용자의 요구에 관해서

+0

꽤 좋지만 OnHandleCreated()를 재정의하여 안정적으로 작동해야합니다. 그리고 인수는 ByVal이어야합니다. –

+0

선생님, 코드를 편집하여 더 효율적으로 만드실 수 있겠습니까? 매번 내가 움직일 수없는 형태를 만들 때, 나는 보통 그렇게한다. –

+0

@HansPassant 당신은 재정의가 필요하다는 점에서 정확합니다. 하지만 존의 해결책은 도움이되지 않을 것입니다. – ThN

0

더 나은 답 : (? 어쩌면 MouseDown에 움켜)

Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Integer, ByVal uParam As Integer, ByRef lpvParam As String, ByVal fuWinIni As Integer) As Integer 

Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Integer, ByVal uParam As Integer, ByRef lpvParam As Long, ByVal fuWinIni As Integer) As Integer 

Private Const SPI_GETDRAGFULLWINDOWS = 38 
Private Const SPI_SETDRAGFULLWINDOWS = 37 
Private Const SPIF_SENDWININICHANGE = 2 

Private Sub frmMain_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move 
Dim result As Long 
result = SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, 1&, vbNullString, SPIF_SENDWININICHANGE) 
Me.Location = New Point(0, 0) 
result = SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, 0&, vbNullString, SPIF_SENDWININICHANGE) 

End Sub 

지금 초기 위치로 Me.Location = 새로운 포인트 (0, 0)를 설정 할 수 있어야한다

0

당신은 양식이 시도 할 수 있습니다 :

public partial class TestForm : Form { 

    private const int HT_CAPTION = 0x2; 
    private const int WM_NCLBUTTONDOWN = 0xA1; 

    [DllImportAttribute("user32.dll")] 
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); 

    public TestForm() { 
    InitializeComponent(); 
    this.ControlBox = false; 
    } 

    protected override void WndProc(ref Message m) { 
    if (m.Msg == Win32.WM_NCLBUTTONDOWN) { 
     Form moveForm = new Form(); 
     moveForm.FormBorderStyle = FormBorderStyle.None; 
     moveForm.StartPosition = FormStartPosition.Manual; 
     moveForm.ShowInTaskbar = false; 
     moveForm.TransparencyKey = Color.Lime; 
     moveForm.BackColor = Color.Lime; 
     moveForm.SetBounds(this.Left, this.Top, this.Width, this.Height); 
     moveForm.Paint += moveForm_Paint;   
     moveForm.Show(); 
     SendMessage(moveForm.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); 
     moveForm.Paint -= moveForm_Paint; 
     moveForm.Close(); 
    } else { 
     base.WndProc(ref m); 
    } 
    } 

    void moveForm_Paint(object sender, PaintEventArgs e) { 
    using (Pen p = new Pen(Color.Gray, 7)) { 
     p.Alignment = System.Drawing.Drawing2D.PenAlignment.Center; 
     e.Graphics.DrawRectangle(p, ((Form)sender).ClientRectangle); 
    } 
    } 
} 

그것은 비 클라이언트 영역이 mousedown 왼쪽 버튼을 차단 국경 주변에 회색 사각형을 그립니다 투명한 폼까지 팝, 그리고 메사를 전송 ge을 클릭하면 양식을 움직일 수 있습니다.