Make similar "magnetic" windows like Winamp
Be famous
Abstract: Winamp's users know that Winamp's playlist or equalizer is moved when being moved, as if it will be magnetic, whenever close to the main window, it is "adsorbed" in the past, and automatically aligned along the side. Keywords: "Magnetic" window category: User interface CODELPHI.COM copyright, unauthorized, users who reprpled Winamp can be reproduced, WINAMP playlists or equalizers are moved when they are moved, as if they are subject to one Magnetic, whenever close to the main window, it is "adsorbed" in the past, and automatically aligns along the side. I want my WINAMP plugin to have this wonderful character, so I figure out a method of "magnetization" window. This method is suitable for all versions of Delphi. To demonstrate this technology, please make a sample program that will be "attracted" by WinAmp. First create an application project, make the main window Form1, and set BorderStyle to BSNOne. Put a button component, double-click it and write "close;" in the onclick event. The procedure will be completed at the time of it. Now switch to the code editing area, define several global variables. Var form1: tform1; // "Magnetic" window Lastx, Lasty: integer; // Remove the previous coordinate WINAMPRECT: TRECT; / / Save the WinAmp window's rectangular area hwnd_winamp: hwnd; // WinAmp window control handle then write Form1 OnMouseDown and onmousemove events. Procedure TForm1.FormMouseDown (Sender: Tobject; Button: TMouseButton; Shift: TshiftState; x, y: integer; const classname = 'winamp v1.x'; // WINAMP main window class name // If you change to classname = ' TAPPBUILDER ', you will find that even Delphi is also gravitated! Begin // Record the current coordinate Lastx: = X; Lasty: = Y; // Find WINAMP HWND_WINAMP: = FINDWINDOW (ClassName, NIL); if hwnd_winamp> 0 THEN / SEN // Record its window area getWindowRect (hwnd_winamp, winamprect) End; Procedure TFORM1.FORMMMOMEMOVE (Sender: Tobject; Shift: TshiftState; x, y: integer); var NLEFT, NTOP: INTEGER; // Record new position temporary variable begin // Check if the left mouse button is pressed if HiWord (GetasyncKeyState)> 0 Then Begin // Calculate New Coordinate NLEFT: = Left X - Lastx; Ntop: = TOP Y - Lasty; // If you find WinAmp, correct the above coordinates, generate "magnetization" effect IF HWnd_WINAMP> 0 THEN MAGNETIZE (NLEFT, NTOP); // Reset window location setbounds (NLEFT, NTOP, WIDTH, Height); end; end; don't worry, look at the magnetize () process, first understand the principle of correcting coordinates .
According to the observation of WinAmp implementation, I fight for the so-called "magnetization" next simple definition, that is, "close to a certain level of a certain level in the original window, by correcting the coordinates of the original window, so that the two windows are in the same plane and have The process of public side. According to this definition, I designed the following "magnetization" steps. The first step is to determine whether the target window (ie Winamp) and our Form1 are overlapping in the horizontal and vertical direction. "A directional projection line has overlap" is a necessary non-sufficient condition "need to be corrected". The judgment is based on the difference between the two projection line segments to the leftmost boundary difference to the width and value of the width and value. In the second step, it is judged that the two window corresponds to whether the boundary is close enough. If you are sure, let them close. Ok, the following is the "mysterious" Magnetize process ... Procedure TForm1.magnetize (VAR NL, NT: Integer); // Inline two compared to size Function min (a, b: integer): integer; Begin if A> b Then Result: = b Else Result: = a; end; function max (a, b: integer): integer; begin if a end; var h_overlapped, v_overlapped: boolean; // Record whether the projection line overlapping TW , ww, wh: integer; // Temporary variable const magneticforce: integer = 50; // "Magnetic" size. // Accurately, it is to correct the coordinates when the edge of the control window is maximum. // For demonstration, here is a relatively exaggerated number - 50. / / Can generally use 20 or so, which is close to WINAMP effect BeGin // whether there is an overlapping projection Ww: = WinAmpRect.right-winamprect.LinampRect.right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LinAmpRect.right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LinAmpRect.right-WinAmpRect.LinAmpRect.right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LINAMPRECT.Right-WinAmpRect.LINAMPRECT (WINAMPRECT.RIGHT, NL WIDTH) -MIN (WINAMPRECT) .Left, nl); h_overlapped: = TW <= (width ww); // Returns the vertical direction WH: = WINAMPRECT.BOTTOM-WINAMPRECT.TOP; TW: = Max (WinampRect.bottom, NT Height) -min (WinampRect.top , nt); V_Overlapped: = tw <= (Height wh); // close enough, then to adjust the coordinates if H_Overlapped then begin if Abs (WinampRect.Bottom-nt) else if Abs (nt Height-WinampRect.Top) end; if V_Overlapped then Begin if ABS (WINAMPRECT.RIGHT-NL) ELSE IF ABS (NL Width-WinampRect.Left) end; end; how? Good effect after running! A karaoke plugin I designed applies this technology, you can go to http://www.lotof.com/lyrics to download it as a reference contributor: SU30
Submission date: 2001-7-30 9:44:00