एक सीमाहीन रूप को चल बनाने के लिए?


109

क्या कोई ऐसा फ़ॉर्म बनाने का कोई तरीका है जिसकी कोई सीमा नहीं है (FormBorderStyle को "कोई नहीं" पर सेट किया जा सकता है) चल जब माउस को फॉर्म पर क्लिक किया जाता है जैसे कि कोई सीमा थी?

जवाबों:


252

कोडप्रोजेक्ट पर यह लेख एक तकनीक का विवरण देता है। मूल रूप से उबलता है:

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

[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool ReleaseCapture();

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}

यह अनिवार्य रूप से खिड़की प्रबंधक के दृष्टिकोण से, खिड़की के शीर्षक पट्टी को हथियाने के समान ही करता है


यह मेरे लिए बिल्कुल भी काम नहीं करता है। कोड ठीक चलता है, सब कुछ सही है, और मेरी खिड़की अभी भी वहीं बैठी है। कोई विचार?
dbrree

8
@dbrree आपने संभवतः कोड की प्रतिलिपि बनाई है, जो Form1_MouseDownवास्तविक MouseDownघटना के लिए असाइन नहीं की गई है Form1
रेमोन रामी

2
यदि आपके पास एक लेबल या एक आइकन (या किसी अन्य अग्रभूमि ऑब्जेक्ट!) है जहाँ आप ड्रैग करने के लिए फ़ॉर्म को हथिया रहे हैं, तो इन आइटम्स में मूसडाउन ईवेंट भी जोड़ें। प्रपत्र ईवेंट फ़ॉर्म ऑब्जेक्ट्स के माध्यम से नहीं देख सकते हैं।
पॉल नेल्सन

1
आपको फॉर्म के लिए फ़ंक्शन को जोड़ना this.MouseDown += ...होगाMain()
रिचर्ड पेक

1
मेरे लिए एक जादू की तरह काम किया!!!! मुझे उस घटना से निपटने के लिए उस पैनल को स्थानांतरित करना पड़ा जिसे मैं फॉर्म की जगह पर रख रहा था, लेकिन इसने काम किया
जस्टिन

54

आइए किसी भी चीज़ को जितना मुश्किल होना चाहिए उससे अधिक कठिन नहीं बनाते हैं। मेरे पास कोड के इतने सारे स्निपेट्स हैं जो आपको एक फॉर्म (या किसी अन्य नियंत्रण) के चारों ओर खींचने की अनुमति देते हैं। और उनमें से कई की अपनी कमियां / दुष्प्रभाव हैं। विशेष रूप से उन लोगों को जहां वे विंडोज को यह सोचकर चकमा देते हैं कि एक फॉर्म पर नियंत्रण वास्तविक रूप है।

कहा जा रहा है, यहाँ मेरा स्निपेट है। मैं इसका हर समय उपयोग करता हूं। मैं यह भी नोट करना चाहूंगा कि आपको इसका उपयोग नहीं करना चाहिए। Invalidate (); जैसा कि अन्य लोग करना पसंद करते हैं क्योंकि यह कुछ मामलों में झिलमिलाहट का कारण बनता है। और कुछ मामलों में ऐसा होता है। रीफ्रेश। इस का उपयोग करते हुए, मैं किसी भी चंचल मुद्दों नहीं है:

private bool mouseDown;
private Point lastLocation;

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown = true;
        lastLocation = e.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if(mouseDown)
        {
            this.Location = new Point(
                (this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);

            this.Update();
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        mouseDown = false;
    }

1
खतरे की खबरें ... इस जवाब के लिए लगभग दो घंटे तक देखा .... im new to c # हालांकि, आपने मुझे आश्चर्यचकित कर दिया!
प्रिंसऑफ रेवेंस

यह ठीक उसी तरह से है जैसा मैंने सोचा था, मेरा एकमात्र मुद्दा यह था कि जब तक आपने इसे कैसे पढ़ा, तब तक सभी नरक के रूप में छोटी गाड़ी थी। धन्यवाद दोस्त
EasyBB

यह एक मेरे लिए बेहतर काम करता था अद्भुत छोटे स्निपेट से अधिक ओवरराइड्स वंडप्रोक। आपका मन करता है, WndProc ने काम किया ... इसने अन्य चीजों को काम करने से रोक दिया। धन्यवाद!
मम्म

शायद यहाँ सबसे अच्छा विकल्प है क्योंकि यह अच्छी तरह से काम करता है और WndProc पर भरोसा नहीं करता है (मोनो के साथ अन्य प्लेटफार्मों पर आसानी से पोर्ट किया जा सकता है)। राज्य को अधिकतम / सामान्य में बदलकर बेहतर किया जा सकता है यदि Y <10
सिल्वरड्रेग

यह मोनो पर काम नहीं करता है, .net 4.5.2 से मोनो / नेट 4.5 पर बदल जाता है और फिर भी काम नहीं करता है। अब इसका समाधान खोजने की कोशिश की जा रही है।
रोजर डीप

35

एक ही काम करने का एक और सरल तरीका।

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        // set this.FormBorderStyle to None here if needed
        // if set to none, make sure you have a way to close the form!
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == WM_NCHITTEST)
            m.Result = (IntPtr)(HT_CAPTION);
    }

    private const int WM_NCHITTEST = 0x84;
    private const int HT_CLIENT = 0x1;
    private const int HT_CAPTION = 0x2;
}

1
इसे संभव बनाने वाला कोई भी व्यक्ति एक विशिष्ट उपकरण (जैसे एक लेबल) पकड़ कर प्रपत्र को स्थानांतरित कर सकता है।
थॉमस डब्ल्यू

2
यदि डबल-क्लिक किया जाता है, तो फ़ॉर्म अधिकतम हो जाता है। यहां भी पढ़ें और यह भी कि यह राइट क्लिक को तोड़ता है।
सेबेस्टियानो

19

माउसडाउन, माउसमोव और माउसअप का उपयोग करें। आप उसके लिए एक वैरिएबल फ्लैग सेट कर सकते हैं। मेरे पास एक नमूना है, लेकिन मुझे लगता है कि आपको संशोधित करने की आवश्यकता है।

मैं माउस कार्रवाई को एक पैनल पर कोड कर रहा हूं। एक बार जब आप पैनल पर क्लिक करते हैं, तो आपका फॉर्म इसके साथ आगे बढ़ जाएगा।

//Global variables;
private bool _dragging = false;
private Point _offset;
private Point _start_point=new Point(0,0);


private void panel1_MouseDown(object sender, MouseEventArgs e)
{
   _dragging = true;  // _dragging is your variable flag
   _start_point = new Point(e.X, e.Y);
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
   _dragging = false; 
}

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
  if(_dragging)
  {
     Point p = PointToScreen(e.Location);
     Location = new Point(p.X - this._start_point.X,p.Y - this._start_point.Y);     
  }
}

यह है। जैसा कि पहले ही कहीं और कहा गया है, यह अभी भी माउसओम घटनाओं को उत्पन्न करने वाले रूप पर निर्भर करता है। एक साधारण मामले के रूप में, मान लीजिए कि आपने सबसे शीर्ष पिक्सेल पंक्ति में फ़ॉर्म को वर्गीकृत किया है और ऊपर की ओर खींचें। कुछ भी नहीं होगा, हालाँकि जैसे ही आप माउस को वापस घुमाएंगे, यह फ़ॉर्म चारों ओर कूद जाएगा।
जॉय

12

केवल WPF


हाथ में सटीक कोड नहीं है, लेकिन हाल ही में एक परियोजना में मुझे लगता है कि मैंने माउसडाउन इवेंट का उपयोग किया और बस इसे डाल दिया:

frmBorderless.DragMove();

Window.DragMove विधि (MSDN)


2
हालांकि, WPF है। ठीक है, ओपी वास्तव में यह निर्दिष्ट नहीं किया था।
जोय

हाँ, जो कुछ मैं इस परियोजना के बारे में भूल गया था जो मैं कर रहा था। मैंने सिर्फ फॉर्म देखे और यह उपलब्ध नहीं है। माफ़ करना!
क्रिस

3
@ क्रिस यह एक WPF परियोजना में मेरे लिए काम किया। उत्तर को न हटाने के लिए धन्यवाद।
रेमबनेटर

7

संदर्भ। वीडियो लिंक

यह परीक्षण और समझने में आसान है।

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case 0x84:
            base.WndProc(ref m);
            if((int)m.Result == 0x1)
                m.Result = (IntPtr)0x2;
            return;
    }

    base.WndProc(ref m);
}

6
यह कोड काम करता है, लेकिन इसे समझना कितना आसान है? मुझे स्विच कोड के अलावा इस कोड सेगमेंट में कुछ भी नहीं पता है!
जमशेद कामरान

यह WM_NCHITTESTभेस में है।
एंड्रियास रिजेब्रैंड

4

कोई संपत्ति नहीं है जिसे आप फ्लिप कर सकते हैं यह सिर्फ जादुई रूप से हो सकता है। फार्म के लिए घटनाओं को देखो और यह सेट करके ऐसा लागू करने के लिए काफी तुच्छ हो जाता है this.Topऔर this.Left। विशेष रूप से आप देखना चाहते हैं MouseDown, MouseUpऔर MouseMove


मुझे लगा कि मुझे उन घटनाओं का उपयोग करना होगा, लेकिन मुझे यकीन नहीं है कि उनके साथ क्या करना है। जब माउसडाउन इवेंट कहा जाता है, तो मैं फॉर्म को स्थानांतरित करने की अनुमति कैसे दूं?
उपयोगकर्ता 7

1
नीचे माउस पर आप एक ध्वज सेट करते हैं और आधार निर्देशांक को संग्रहीत करते हैं। माउस चाल पर - यदि ध्वज सेट है - आप नए माउस निर्देशांक की ऑफसेट द्वारा शीर्ष और बाएं समायोजित करते हैं। माउस पर आप ध्वज को साफ़ करें।
मर्फ़

फिर भी, आप इसे विंडोज एपीआई के साथ काफी आसान कर सकते हैं जो अभी भी माउस घटनाओं पर निर्भर नहीं करता है। यह विधि विफल हो जाती है यदि आप प्रपत्र के बहुत ऊपरी किनारे पर पिक्सेल को पकड़ते हैं और उदाहरण के लिए ऊपर की ओर खींचें।
जॉय

4
public Point mouseLocation;
private void frmInstallDevice_MouseDown(object sender, MouseEventArgs e)
{
  mouseLocation = new Point(-e.X, -e.Y);
}

private void frmInstallDevice_MouseMove(object sender, MouseEventArgs e)
{
  if (e.Button == MouseButtons.Left)
  {
    Point mousePos = Control.MousePosition;
    mousePos.Offset(mouseLocation.X, mouseLocation.Y);
    Location = mousePos;
  }
}

इससे उर समस्या का समाधान हो सकता है ...।


आप Control.ousePosition के बजाय "e.Location" का भी उपयोग कर सकते हैं
रेजा तैबुर

4

https://social.msdn.microsoft.com/Forums/vstudio/en-US/d803d869-68e6-46ff-9ff1-fabf78d6393c/how-to-make-a-borderless-form-in-c?forum=csharpgeneral

उपरोक्त लिंक से कोड के इस बिट मेरे मामले में चाल किया :)

protected override void OnMouseDown(MouseEventArgs e)  

{
      base.OnMouseDown(e);
      if (e.Button == MouseButtons.Left)
      {
        this.Capture = false;
        Message msg = Message.Create(this.Handle, 0XA1, new IntPtr(2), IntPtr.Zero);
        this.WndProc(ref msg);
      }
}

4

सबसे अच्छा तरीका जो मैंने पाया है (पाठ्यक्रम का संशोधित)

// This adds the event handler for the control
private void AddDrag(Control Control) { Control.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DragForm_MouseDown); }
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private void DragForm_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        // Checks if Y = 0, if so maximize the form
        if (this.Location.Y == 0) { this.WindowState = FormWindowState.Maximized; }
    }
}

एक नियंत्रण में ड्रैग को लागू करने के लिए इसे InitializeComponent () के बाद डालें

AddDrag(NameOfControl);

4

इसने मेरे लिए काम किया।

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        _mouseLoc = e.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            int dx = e.Location.X - _mouseLoc.X;
            int dy = e.Location.Y - _mouseLoc.Y;
            this.Location = new Point(this.Location.X + dx, this.Location.Y + dy);
        }
    }

स्टैक ओवरफ्लो में आपका स्वागत है - दौरे , कृपया उत्तर की जांच करें । आपको इस बारे में स्पष्टीकरण देना होगा कि यह कोड ओपी "मूल पोस्टर" की समस्या को कैसे हल करता है। यह आपके उत्तर की जाँच करने वाले किसी भी व्यक्ति के लिए अधिक उपयोगी होगा।
मौरिसियो एरियस ओल्वे

2

.NET फ्रेमवर्क 4 के लिए,

आप घटक this.DragMove()की MouseDownघटना के लिए उपयोग कर सकते हैं (इस उदाहरण में mainLayout) जिसे आप खींचने के लिए उपयोग कर रहे हैं।

private void mainLayout_MouseDown(object sender, MouseButtonEventArgs e)
{
    this.DragMove();
}

2

सबसे आसान तरीका है:

सबसे पहले लेबल 1 नाम का एक लेबल बनाएं। लेबल 1 के ईवेंट> माउस ईवेंट> लेबल 1_ मीडिया पर जाएं और इन्हें लिखें:

if (e.Button == MouseButtons.Left){
    Left += e.X;
    Top += e.Y;`
}

2

मैं एक सीमा रहित विन्डोज़ फॉर्म को चल बनाने की कोशिश कर रहा था जिसमें एक WPF एलिमेंट होस्ट कंट्रोल और एक WPF यूजर कंट्रोल था।

मैंने अपने WPF उपयोगकर्ता नियंत्रण में StackPanel नामक एक स्टैक पैनल के साथ समाप्त किया जो कि स्थानांतरित करने के लिए क्लिक करने की कोशिश करने के लिए तार्किक बात लगती थी। जब मैंने माउस को धीरे-धीरे खिसकाया, तब जन्नत के कोड को आज़माते हुए काम किया, लेकिन अगर मैंने माउस को तेज़ी से हिलाया, तो माउस फॉर्म से दूर हो जाएगा और फॉर्म कहीं बीच में अटक जाएगा।

कैप्चरमाउस और रिलीज़कैप्ट्योरमाउस का उपयोग करके मेरी स्थिति के लिए उनके जवाब में यह सुधार हुआ और अब माउस इसे स्थानांतरित करने के बावजूद फॉर्म को स्थानांतरित नहीं करता है, भले ही मैं इसे जल्दी से स्थानांतरित कर दूं।

private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
{
    _start_point = e.GetPosition(this);
    StackPanel.CaptureMouse();
}

private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
{
    StackPanel.ReleaseMouseCapture();
}

private void StackPanel_MouseMove(object sender, MouseEventArgs e)
{
    if (StackPanel.IsMouseCaptured)
    {
        var p = _form.GetMousePositionWindowsForms();
        _form.Location = new System.Drawing.Point((int)(p.X - this._start_point.X), (int)(p.Y - this._start_point.Y));
    }
}

    //Global variables;
    private Point _start_point = new Point(0, 0);

2

चूँकि कुछ उत्तर बाल नियंत्रणों को खींचने योग्य नहीं होने देते, इसलिए मैंने थोड़ा सहायक वर्ग बनाया है। इसे शीर्ष स्तर के रूप में पारित किया जाना चाहिए। यदि वांछित हो तो अधिक सामान्य बनाया जा सकता है।

class MouseDragger
{
    private readonly Form _form;
    private Point _mouseDown;

    protected void OnMouseDown(object sender, MouseEventArgs e)
    {
        _mouseDown = e.Location;
    }

    protected void OnMouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            int dx = e.Location.X - _mouseDown.X;
            int dy = e.Location.Y - _mouseDown.Y;
            _form.Location = new Point(_form.Location.X + dx, _form.Location.Y + dy);
        }
    }
    public MouseDragger(Form form)
    {
        _form = form;

        MakeDraggable(_form);            
    }

    private void MakeDraggable(Control control)
    {
        var type = control.GetType();
        if (typeof(Button).IsAssignableFrom(type))
        {
            return;
        }

        control.MouseDown += OnMouseDown;
        control.MouseMove += OnMouseMove;

        foreach (Control child in control.Controls)
        {
            MakeDraggable(child);
        }
    }
}

1

इसके अलावा, यदि आपको डबल क्लिक करने और अपने फॉर्म को बड़ा / छोटा करने की आवश्यकता है, तो आप पहले उत्तर का उपयोग कर सकते हैं, एक वैश्विक int वैरिएबल बना सकते हैं, आपके द्वारा ड्रैग करने के लिए उपयोग किए जाने वाले घटक पर हर बार 1 क्लिक जोड़ सकते हैं। यदि variable == 2तब आपका फॉर्म बड़ा / छोटा हो जाता है। इसके अलावा हर आधे सेकंड के लिए एक टाइमर का उपयोग करें या अपना बनाने के लिए एक सेकंड variable = 0;


1

मेनविंडो में एक MouseLeftButtonDownइवेंट हैंडलर जोड़ना मेरे लिए काम कर गया।

स्वचालित रूप से उत्पन्न होने वाले ईवेंट फ़ंक्शन में, निम्न कोड जोड़ें:

base.OnMouseLeftButtonDown(e);
this.DragMove();

1

मैं jay_t55 से एक और विधि के साथ समाधान का विस्तार कर रहा हूं ToolStrip1_MouseLeaveजो माउस के घटना को जल्दी से स्थानांतरित करने और क्षेत्र को छोड़ने के लिए संभालता है।

private bool mouseDown;
private Point lastLocation;

private void ToolStrip1_MouseDown(object sender, MouseEventArgs e) {
    mouseDown = true;
    lastLocation = e.Location;
}

private void ToolStrip1_MouseMove(object sender, MouseEventArgs e) {
    if (mouseDown) {
        this.Location = new Point(
            (this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);

        this.Update();
    }
}

private void ToolStrip1_MouseUp(object sender, MouseEventArgs e) {
    mouseDown = false;
}

private void ToolStrip1_MouseLeave(object sender, EventArgs e) {
    mouseDown = false;
}

0

मैंने निम्नलिखित और प्रेस्टो परिवर्तन की कोशिश की, मेरी पारदर्शी खिड़की अब जगह में जमी नहीं थी, लेकिन स्थानांतरित की जा सकती थी !! (ऊपर उन सभी अन्य जटिल समाधानों को फेंक दें ...)

   private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);
        // Begin dragging the window
        this.DragMove();
    }

यह उत्तर WPF के लिए है, यह सवाल WinForms के बारे में है।
रे

0

फॉर्म 1(): new Moveable(control1, control2, control3);

वर्ग:

using System;
using System.Windows.Forms;

class Moveable
{
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();
    public Moveable(params Control[] controls)
    {
        foreach (var ctrl in controls)
        {
            ctrl.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    ReleaseCapture();
                    SendMessage(ctrl.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
                    // Checks if Y = 0, if so maximize the form
                    if (ctrl.FindForm().Location.Y == 0) { ctrl.FindForm().WindowState = FormWindowState.Maximized; }
                }
            };
        }
    }
}

0
   [DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
    private extern static void ReleaseCapture();

    [DllImport("user32.DLL", EntryPoint = "SendMessage")]
    private extern static void SendMessage(System.IntPtr hWnd, int Msg, int wParam, int lParam);
    private void panelTitleBar_MouseDown(object sender, MouseEventArgs e)
    {
        ReleaseCapture();
        SendMessage(this.Handle, 0x112, 0xf012, 0);
    }

यह अच्छा होगा यदि आप कुछ स्पष्टीकरणों के साथ अपने उत्तर का समर्थन करते हैं :)
मुस्तफाम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.