Like QQ form, the form is automatically hidden and displayed when it is moved to the top

[example introduction]

Float and hide forms like qq

[example screenshot]


File: 590m.com/f/25127180-494401701-caf72f (access password: 551685)

[[core code]


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
 
namespace Floating and hiding of forms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        #region public variable
        IntPtr Tem_Handle;//Get handle of control and form
        Point CPoint;//Gets the coordinates of the mouse in the control
        int Tem_Y = 0;
        #endregion
 
        #Region API declaration
        //Gets the handle of the visual control under the current mouse
        [DllImport("user32.dll")]
        public static extern int WindowFromPoint(int xPoint, int yPoint);
        //Gets the parent handle of the specified handle
        [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        public static extern IntPtr GetParent(IntPtr hWnd);
        //Gets the size of the screen
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        private static extern int GetSystemMetrics(int mVal);
        #endregion
 
        #region gets the handle of the visual control under the current mouse
        /// <summary>
        ///Gets the handle of the visual control under the current mouse
        /// </summary>
        ///< param X = "int" > X coordinate of the current mouse < / param >
        ///< param Y = "int" > Y coordinate of current mouse < / param >
        public IntPtr FormNameAt(int x, int y)
        {
            IntPtr Tem_hWnd;//Sets the variable that stores the handle
            Tem_Handle = (IntPtr)(WindowFromPoint(x, y));//Gets the handle of the visual control under the current mouse
            Tem_hWnd = Tem_Handle;//Record original handle
            while (Tem_hWnd != ((IntPtr)0))//Traverse the parent handle of the handle
            {
                Tem_Handle = Tem_hWnd;//Record current handle
                Tem_hWnd = GetParent(Tem_hWnd);//Get parent handle
            }
            return Tem_Handle;//Returns the lowest parent handle
        }
        #endregion
 
 
        private void timer1_Tick(object sender, EventArgs e)
        {
                if (this.Top < 3)//If the form is moved to the top of the screen
                {
                    if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//When the mouse moves over the form
                    {
                        panel_Title.Tag = 1;//Set the identification to determine whether the form is at the top of the screen
                        timer2.Enabled = false;//Do not stretch the form
                        this.Top = 0;//Top form
                    }
                    else
                    {
                        panel_Title.Tag = 1;//Set the logo to judge whether the form is at the top of the screen
                        timer2.Enabled = true;//Hide form at top
                    }
                }
                else
                {
                    if (this.Left < 3 || this.Right > GetSystemMetrics(0) - 3)//If the form is moved to the left or right end of the screen
                    {
                        if (this.Left < 3)//If the form is moved to the left end of the screen
                        {
                            if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//When the mouse moves over the form
                            {
                                panel_Title.Tag = 2;//Set the identification, which is used to judge that the form is at the left end of the screen
                                timer2.Enabled = false;
                                this.Left = 0;//Make the form to the left
                            }
                            else
                            {
                                panel_Title.Tag = 2;
                                timer2.Enabled = true;//Hide the form at the left end
                            }
                        }
                        if (this.Right > GetSystemMetrics(0) - 3)//If the form is moved to the right end of the screen
                        {
                            if (this.Handle == FormNameAt(Cursor.Position.X, Cursor.Position.Y))//When the mouse moves over the form
                            {
                                panel_Title.Tag = 3;//Set the identification, which is used to judge that the form is at the right end of the screen
                                timer2.Enabled = false;
                                this.Left = GetSystemMetrics(0) - this.Width;//Make form right
                            }
                            else
                            {
                                panel_Title.Tag = 3;
                                timer2.Enabled = true;//Hide the form at the right end
                            }
                        }
 
                    }
                }
 
        }
 
        private void timer2_Tick(object sender, EventArgs e)
        {
            switch (Convert.ToInt16(panel_Title.Tag.ToString()))//Judge the identification
            {
                case 1://Top hidden
                    {
                        if (this.Top < 5)
                            this.Top = -(this.Height - 2);
                        break;
                    }
                case 2://Left end hidden
                    {
                        if (this.Left < 5)
                            this.Left = -(this.Width - 2);
                        break;
                    }
                case 3://Right end hidden
                    {
                        if ((this.Left   this.Width) > (GetSystemMetrics(0) - 5))
                            this.Left = GetSystemMetrics(0) - 2;
                        break;
                    }
            }
        }
 
        private void panel1_Click(object sender, EventArgs e)
        {
            this.Close();
        }
 
        #region uses the controls on the form to move the form
        /// <summary>
        ///Use controls to move forms
        /// </summary>
        ///< param frm = "form" > form < / param >
        ///< param e = "mouseeventargs" > control's move event < / param >
        public void FrmMove(Form Frm, MouseEventArgs e)  //Form or MouseEventArgs add namespace using system Windows. Forms;
        {
            if (e.Button == MouseButtons.Left)
            {
                Point myPosittion = Control.MousePosition;//Gets the screen coordinates of the current mouse
                myPosittion.Offset(CPoint.X, CPoint.Y);//Reloads the current mouse position
                Frm.DesktopLocation = myPosittion;//Sets the position of the current form on the screen
            }
        }
        #endregion
 
        private void panel_Title_MouseDown(object sender, MouseEventArgs e)
        {
            timer1.Enabled = false;
            CPoint = new Point(-e.X, -e.Y);
        }
 
        private void panel_Title_MouseMove(object sender, MouseEventArgs e)
        {
            FrmMove(this, e);
        }
 
        private void panel_Title_MouseUp(object sender, MouseEventArgs e)
        {
            timer1.Enabled = true;
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            this.TopMost = true;
        }
    }
}

The following are irrelevant:

-------------------------------------------Split line---------------------------------------------

Java generics are J2 SE1 A new feature introduced in 5 is essentially a parameterized type, that is, the data type operated is specified as a parameter. This parameter type can be used in the creation of classes, interfaces and methods, which are called generic classes, generic interfaces and generic methods respectively.

generic method
The general definition is as follows, that is, a method is added in front of it

public class FTest {
public List f(T t){...};
}
Three generic parameter inference methods:

1. Directly precede f() with a definite generic type

fTest.f(xxx)
2. Determined by the input parameters, the following is inferred as Integer

int number = 0;
fTest.f(number)
3. It can be determined by the return value

List list = fTest.f(xxx);
Q: What's wrong with the following code? Is toString() there?

public class A {
public static void test(T t){
System.out.println(t.toString());
}
}
A: test is a static method, so T in instance a cannot be sensed
Need to be changed to
public static void test(T t)

There is no problem with toString (). ToString is the method of Object.

Generic parameters and type elimination
Q: What will the generic parameter T become at run time?
A: It becomes an Object and does not contain any type of information.

Q: Can the generic parameter T be compared with instanceof?

Copy code
class A {
void f(Object arg)
if(arg instanceof T) {
...
}
}
Copy code
A: No, the compiler will report an error.

Q: Can generic parameter T perform new T() or new T [] operations?
A: No, the compiler will report an error.

Q: Can I call a method in a generic parameter object?

T.f();
A: Only methods of Object can be called.

Q: Can T be used for forced conversion?

T t = (T)object;
A: It can run, but it will not really transform. Warning warning will be triggered during compilation.

Problems when creating new generic objects
First assume that there are two classes, the base class Parent and the subclass Child

class Parent{}
class Child extends Parent{}
Answer the following questions:
Q: Is there a problem with the following sentence?

List list = new ArrayList()
A: If there is a problem, the compilation is wrong. List and ArrayList have no parent-child relationship

Q:

List<? extends Parent> list = new ArrayList();
What are the characteristics of this list?

A: This list can call a = list Get(), but not list add(new Parent())

reason:
list. The operation done by get() is to return the internal <? Extend Parent > strong conversion to Parent is reasonable. Any subclass of Parent can be converted to Parent
list. The operation of add (New Parent()) is to convert the external A into the internal <? Extend Parent >, which is unreasonable because we don't know which Parent's subclass this Parent object can be converted to.
Q:

List<? super Child> list = new ArrayList();
What are the characteristics of this list?
Who will report an error

list.add(new Child())
list.add(new Parent())
Parent a= list.get();
Child b = list.get()
A: The screenshot is as follows:

Child c = list.get() or parent P = list The operation done by get() is to return the internal <? Super child > strong conversion to external parent or child is unreasonable, because the compiler thinks that the parent class of child may not be able to be converted to parent or child, so this behavior is prohibited (for example, the parent class of parent is object, but object may not be able to be converted to parent or child)* list. The operation of add (New child()) is to convert the external child or parent into the internal <? Super child >, which is reasonable, because child and parent must be able to become the parent of child.
Q:

List<?> list = new ArrayList();
What are the characteristics of this list?

A: Neither get nor add can work. Only remove and other operations without return value and input a can be performed.
PS: note that it doesn't mean you can't call get or add methods, but when you call get or add, you can't use the object A to operate.
That is, add(A) or a = get (0) cannot be done
But you can do add(object) or Object o = get(0)
Because? Can be converted to Object, but cannot be converted to A.

Q: Will the following code report an error?

Copy code
List fruitList = new ArrayList<>();
fruitList.add(new Fruit());
List appleList = new ArrayList<>();
appleList.add(new Apple());
fruitList.addAll(appleList);
System.out.println(fruitList);
Copy code
A: No error will be reported. The results will be printed normally.

PECS principle
Pay attention to the difference between PECS principle and the above!
Mentioned earlier? extend or? Super is used when declaring objects.
The PECS principle is the method input parameters for generic objects!

Suppose there is a class defined as follows:

Copy code
public static class MyList {
List list = new ArrayList<>();

// Put the input parameters into yourself, which is similar to the production operation
public void pushList(List<T> t) {
    list.addAll(t);
}

// Input the consumption parameters to yourself.
public void pollList(List<T> t) {
     t.addAll(list);
}

}
Copy code
Then T is the generic parameter.

Q: Can the following code work normally?

Copy code
MyList myList = new MyList<>();

List intList = new ArrayList<>();
myList.pushList(intList);

List objectList = new ArrayList<>();
myList.pollList(objectList);
Copy code
A: If it fails to operate normally, pushList and pollList will report errors

Because after checking, the compiler thinks that List and List are not the same thing!

Q: If you want to support pushList above, how should you modify the definition of the pushList method?
A: Change to this:

//Put the input parameters into yourself, which is similar to the production operation
public void pushList(List<? extends T> t) {
list.addAll(t);
}
That is, the compiler thinks that List and List <? Extend number > is a thing that allows!

Q: How to modify the definition if you want to support pollList?
A:

//Stuffing your own content into input parameters is similar to making input parameters consume.
public void pollList(List<? super T> t) {
t.addAll(list);
}
Because you want to put your own things into the input parameters, you must ensure that t is the subclass of the input parameters. Conversely, the input parameters must be the parent of T, so use super
So the compiler thinks, List and List <? Super number > is a thing that allows!

PECS principle comes from Effective Java. Note that it is just a programming suggestion!

If there is a Class A, the generic parameter is T
If it is generally only used to insert its own internal t container after receiving the input container List, class A is called the producer, so the input parameter is best defined as <? Extend T > is best so that it can receive containers of any t subclass.
If it is generally only used to receive the List after the input container and insert its own internal t element into it, then this class A is called a consumer, and the input parameter is best defined as <? Super T > \ best so that your own t element can be stuffed into the parent container of any t element.

Added by ccl on Sat, 19 Feb 2022 10:18:12 +0200