WinAPI Tutorial #3 (Drag Window)

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Art Sentinel.

============
============
============


oooOO Drag Window Tutorial in 5 EASY Steps OOooo

.

.


============
Introduction
============


Sometimes the strangest things happen. Take for example, last week when my toilet spontaneously
exploded.. If I had not gotten up for a brief moment to fetch another roll of paper, my tail end
would probably be orbiting the Earth right now much like a rude white satellite. (That reminds
me of something I just read: Do you know that scientists now believe that the Earth may have
once had two moons while it was first being formed?) :wink:

Equally odd was what happened to me today at the local fast food restaurant. Immediately after
ordering a Large Fry and a 20 piece ChickenNugget, the cashier's eyes rolled back in her head.
She began shouting in what sounded like an ancient Latin dialect. Then, before I could react,
she leaped over the counter lunging towards me. In a panic, I screamed, "I'm sorry!! OK, I only
want the 8 piece ChickenNugget! Please don't hurt me!"

But my fear was allayed as she sailed over my head, leaped the customer line railing like an
Olympic hurdler, and began bashing her head into the Pepsi dispensing machine. After I caught
my breath, I cautiously approached her (being careful to not step in the growing puddle of
cola) and asked, "Why are you bashing your head into that Pepsi dispenser?"

Foaming at the mouth, she glared wild-eyed back at me. Then she cried out, "Because PureBasic
does not have enough tutorials!! And I want to know how to make the client area of a window
draggable based upon any coordinates I decide!"

Obviously I could not let her stand there all day whapping the cola machine with her forehead, so I
agreed to write another WinAPI tutorial.. This one is dedicated to all those moderately
insane fast food employees out there. Please do not hurt the Pepsi. The Pepsi never did you
any harm..

.

.


==============
Tutorial Start
==============


Today I will show in just 5 steps how to make your PB applications draggable without using the
Non-Client Area bar at the top of the window. Not only that, I will demonstrate how you can
specify any coordinates you like to be the 'hotspot' where dragging is possible.

Why would you use such a technique? Well imagine that you want to design an application with
your very own skinnable interface, or one where the window is an odd shape like that of a
ChickenNugget. In both cases, you would very likely choose to exclude the customary windows
title bar and buttons. There are times when Microsoft's default window appearance does not
fill your needs. In situations like this, you will be pleased to know that PureBasic is
completely capable of supporting almost any wacky interface you can think up. :)

.

Important Tips to Remember

- Constants are simply names for numbers, and always begin with a #.
If you were a large number--say 3.14159265358979323846--you could walk around town forcing all
your number friends to call you by your full name, but since you are always the same person
(number) it would be much easier if you chose a nickname. Calling yourself Pi instead would
definitely improve your social status.

This is what a constant is in PureBasic. You are probably already aware of this, but what you
may not realize is that in PB, you can use all the windows constants as well! (PureBasic does
not mind at all, and treats then like an extension of itself.) This gives you a vast arsenal
of quick to use tools. Especially so when you begin delving deeper into the mysteries of the
WinAPI.

- If the floor beneath your toilet ever begins to rumble like a horde of charging Rhinos, RUN!!
Run for your life and don't look back!

- Learn the structure command in PureBasic. What may at first seem to be something you would
not find much use for, will soon become like a best friend once you are comfortable with its
concept and use. Fred kindly added this for us to enable cleaner code, and efficient algorithms.
Some of the most exciting things you can do with the API depend upon structures. If you do not
understand structures, you really are missing out.

- When designing your next application, make use of PB comments. Of course they are very helpful
for leaving yourself notes so that when you look back at your code in three months from now, you
will still be able to quickly tell what each section does. However, another very useful
function of a comment is to block out lines of code while you are testing your application.
When something does not work the way you expect, adding a ; to the
beginning of a few chosen lines of code will allow you to narrow down where exactly the trouble
is originating from.

.

.

Step One

Start a new project and save it under the name 'DragWindow.pb'. Now add the following variable
declarations:

.

.

Code: Select all

Global FixedX.l
Global FixedY.l
Global hWnd.l
#SmallText = 35
#LargeText = 34
FontName$ = "Arial"
.

.

Step Two

Next add the two structures our API calls will refer to:

.

.

Code: Select all

Structure tagPOINT
  x.l
  y.l
  
EndStructure 
Global POINT.tagPOINT

Structure _RECT
  left.l
  top.l
  right.l
  bottom.l
  
EndStructure 
Global RECT._RECT
.

.

The above lines of code are perhaps the most important parts of this tutorial. The API will
directly alter the contents of these structures, which will in turn allow us to easily use
their values to run our application. If you are curious as to why I chose these particular
Structure names and internal values, please scroll to the bottom of this tutorial right now
and read the WinAPI Docs I conveniently included.

Caution: You will notice that I added the Global variables after the structure declarations.
The reason for this is simply because the structure needed to exist first before I began
making references to it.

The PureBasic help says this about structures:

Structure is useful to define user type, and access some OS memory areas. Structures can
be used to enable faster and easier handling of big data files. It could be useful as you
can group into the same object the information which is common. Structures are accessed
with the \ option. Structures can be nested. Static arrays are supported inside structures.


By user type it is meant exactly that. In PB there are bytes (variable.b), long
(variable.l), word (variable.w), float (variable.f), and string (variable.s) types. Using a
structure, you can very easily add you own user types. Want a variable called BigMac of the
type Hamburger? No problem! Just declare it:

.

Code: Select all

Structure Hamburger
   Pickles.l
   Tomatoes.l
   Mayonaise.l
   Beef.l

Code: Select all

EndStructure

Code: Select all

BigMac.Hamburger
.

I know that structures may seem a little daunting at first. One thing that can help you
visualize them and their importance is to think in terms of ActionScript (JavaScript) programming.
Think of PB structures as objects and the internal values as properties. The
stuff inside a structure can be whatever you specify; but by keeping it related to the
structure itself, you will soon discover one of PB's most powerful built-in features.

To access the contents of a structure (either to change it, or to read it), use the following
syntax:

HasBeef.l = BigMac\Beef
HadPickles.l = BigMac\Pickles

This will give you the values of the variables Beef & Pickles.

Step Three

Now we are going to add the brains of our tiny but cool application. We will do this by
using the following procedure:

.

.

Code: Select all

Procedure XY2ClientArea()   
   GetCursorPos_(@POINT)
   GetWindowRect_(hWnd, @RECT)
   FixedX = (POINT\x) - (RECT\left)
   FixedY = (POINT\y) - (RECT\top)
    
EndProcedure 
.

.

Here what we are doing is very basically finding the position of the mouse cursor over the
client area of our window. (The client area of a window is the space within the outer border
and beneath the title bar. The rectangle that comprises your software.)

I just introduced two new API calls in the above procedure. You will be happy to see that
they require very little effort to add once you have the structure properly set up from the
previous step.

GetCursorPos finds the x and y coordinates of the mouse cursor as it relates to the
screen (NOT your application). It then alters your Point Structure, changing the x and y
variables to their new values.

GetWindowRect finds the x and y coordinates of your application's window: the top,
left, bottom, and right edges. hWnd is simply the handle of the window you are checking the
coordinates of. In this case, it is the sole window of our application.

Did you notice the @ signs in the above code? This is because the API call wants an address of
the structure for cursor position and window coordinates. You accomplish this by 'pointing' to
that memory location by appending an @ before the name of the structures. (Sometimes this is
not what is needed, so read the API Docs well!)

Finally, we perform elementary mathematics on the results of the structures to obtain the
mouse's x and y position within our application. The upper left hand corner of our
program represents 0,0.

Step Four

Now what you need to do is open a window (300 pixels X 300 pixels), set it so that it has
no title bar (#PB_Window_BorderLess), and add a couple buttons and one text object. Place
the buttons at the bottom right corner of the window; place the text to the left of the
buttons. These are here as the visual part of your project. You will add commands to the
buttons in the next step. Your newly added code should look similar to this:

.

.

Code: Select all

;Open window
If OpenWindow(0, 150, 150, 300, 300, #PB_Window_BorderLess, "Drag Window API Test")
  hWnd = WindowID()

  Else

  MessageRequester("Error #1,000,230", "Possibly something went wrong somewhere, I think.", #PB_MessageRequester_OK)
  End  

EndIf


;Set button gadget
If CreateGadgetList(hWnd) 
  SmallFont.l = LoadFont(#SmallText, FontName$, 10)
  LargeFont.l = LoadFont(#LargeText, FontName$, 20)
  
  SetGadgetFont(LargeFont)
  TextGadget(12, 0, 100, 300, 30, "PureBasic Rocks!", #PB_Text_Center)
  SetGadgetFont(SmallFont)
  TextGadget(11, 0, 280, 300, 20, "- - - - - - - Drag Here - - - - - - -", #PB_Text_Center) 
  ButtonGadget(007, 286, 286, 14, 14, "X")
  ButtonGadget(008, 272, 286, 14, 14, "-")
  
  Else
  MessageRequester("Sorry..", "This Gadget List accepts exact change only.", #PB_MessageRequester_OK)
  End
  
EndIf
.

.

Step Five

You're almost finished! This is the part where you will design the main loop of your
application. The reason for this is to check if the buttons are pressed, or if the user
clicks and drags over the area at the bottom of the window where the text is placed.

See here:

.

.

Code: Select all

Repeat 

Select WaitWindowEvent()

  Case  #PB_EventGadget
  
    Select EventGadgetID()
    
      Case 007
        Quit =1        
        
      Case 008
        ShowWindow_(hWnd, #SW_MINIMIZE)
    
    EndSelect
     
  Case #WM_LBUTTONDOWN 
    
    XY2ClientArea()
    If ((FixedX > 0 And FixedX  276 And FixedY If the user clicks on the button with the 'X' you will set Quit = 1 so that the application 
ends. If the user clicks on the button labeled '-', you will call a small API function 
[i]ShowWindow[/i]. By specifying these exact parameters, you are telling your application 
to minimize when the '-' button is clicked. (See the WinAPI Docs below for all the other 
fun options to use within this easy API call.) What you have just done is to eliminate 
the need for the title bar and system buttons an application normally contains. You could 
make these as graphical and creative as you like. Thanks to PureBasic and the WinAPI, the 
freedom is all yours.

Lastly, you see that we added a call to our procedure when the user clicks and holds down 
the mouse's left button while over our application. Then we use a simple If ... EndIf 
statement to check that the mouse is within our desired coordinates when its button is 
held down. (You can change these coordinates to your liking, or even add several draggable 
'hotspots' if you choose.) You may notice that I did not extend the 'hotspot area' to 
overlap our buttons at the bottom. If you do overlap them, you will see that the button 
focus no longer works as we would expect. 

When the mouse is held down over our specified area, we then call our final API functions:

.

[code]
ReleaseCapture_()
SendMessage_(hWnd, #WM_NCLBUTTONDOWN, #HTCAPTION, NULL)
.

The first will make sure that no other application (or our own) has decided to capture the
mouse input. If one has, this will free it and allow for normal mouse input processing. A
window that captures the mouse will receive all the mouse input exclusively except when the
mouse button is clicked while the cursor is within another application's window. If you do
not free this up first, the next API call may fail. This is your safeguard.

The SendMessage API call does the last piece of work in our tutorial. It sends a
specified message to our target window, Messages are what run everything. If you close a
window, it sends a close message. If your mouse clicks its buttons, they send messages to
the window involved. If you press keyboard keys, even more messages are passed along. It is our
applications we design that must process these system messages and do the proper things. In this
example, we are sending a message, pretending that we placed our mouse cursor in the title bar
of our application and held the left button down. As you are aware, when you do this, you are
able to drag the window around your desktop. Just because we don't really click our mouse there,
does not mean we cannot fool our application into believing we really did! :wink: And here is
the fascinating 'trick' of API Drag Window Tutorial.

hWnd is the handle of the window we want to send the message to.

#WM_NCLBUTTONDOWN is the message we want sent. (See the WinAPI Docs below for many
more messages you can send instead of this one.)

#HTCAPTION, NULL are the two parameters that our chosen message requires. These
parameters change depending on which message you select to send. #HTCAPTION is our
non-client area hit test message that says, "We will trick our application into thinking
we clicked within the caption area at top." NULL, is there because we are already processing
our x and y coordinates and have no need for this additional process.

.

.

==========
Conclusion
==========

Here is what your final code may look like:

.

.

Code: Select all

;====================
;Drag Window API Test
;Art Sentinel August, 05, 2002
;For everyone at the PureBasic Forum
;====================
;ILYLCBD


;Declare variables
Global FixedX.l
Global FixedY.l
Global hWnd.l
#SmallText = 35
#LargeText = 34
FontName$ = "Arial"


;Declare structures
Structure tagPOINT
  x.l
  y.l
  
EndStructure 
Global POINT.tagPOINT

Structure _RECT
  left.l
  top.l
  right.l
  bottom.l
  
EndStructure 
Global RECT._RECT


;Declare procedures
Procedure XY2ClientArea()   
   GetCursorPos_(@POINT)
   GetWindowRect_(hWnd, @RECT)
   FixedX = (POINT\x) - (RECT\left)
   FixedY = (POINT\y) - (RECT\top)
    
EndProcedure 


;Open window
If OpenWindow(0, 150, 150, 300, 300, #PB_Window_BorderLess, "Drag Window API Test")
  hWnd = WindowID()

  Else

  MessageRequester("Error #1,000,230", "Possibly something went wrong somewhere, I think.", #PB_MessageRequester_OK)
  End  

EndIf


;Set button gadget
If CreateGadgetList(hWnd) 
  SmallFont.l = LoadFont(#SmallText, FontName$, 10)
  LargeFont.l = LoadFont(#LargeText, FontName$, 20)
  
  SetGadgetFont(LargeFont)
  TextGadget(12, 0, 100, 300, 30, "PureBasic Rocks!", #PB_Text_Center)
  SetGadgetFont(SmallFont)
  TextGadget(11, 0, 280, 300, 20, "- - - - - - - Drag Here - - - - - - -", #PB_Text_Center) 
  ButtonGadget(007, 286, 286, 14, 14, "X")
  ButtonGadget(008, 272, 286, 14, 14, "-")
  
  Else
  MessageRequester("Sorry..", "This Gadget List accepts exact change only.", #PB_MessageRequester_OK)
  End
  
EndIf


;Main loop
Repeat 

Select WaitWindowEvent()

  Case  #PB_EventGadget
  
    Select EventGadgetID()
    
      Case 007
        Quit =1        
        
      Case 008
        ShowWindow_(hWnd, #SW_MINIMIZE)
    
    EndSelect
     
  Case #WM_LBUTTONDOWN 
    
    XY2ClientArea()
    If ((FixedX > 0 And FixedX  276 And FixedY 
===================
Related WinAPI Docs
===================


 GetCursorPos  QuickInfo  Overview  Group

The GetCursorPos function retrieves the cursor's position, in screen coordinates. 

BOOL GetCursorPos(

    LPPOINT  lpPoint 	// address of structure for cursor position  
   );	


Parameters

lpPoint

Points to a POINT structure that receives the screen coordinates of the cursor. 
 



Return Value

If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE. To get extended error information, call GetLastError.

Remarks

The cursor position is always given in screen coordinates and is not affected by the mapping mode of the window that contains the cursor. 
The calling process must have WINSTA_READATTRIBUTES access to the window station. 

See Also

ClipCursor, POINT, SetCursor, SetCursorPos, ShowCursor 


========================


 GetWindowRect  QuickInfo  Overview  Group

The GetWindowRect function retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen. 

BOOL GetWindowRect(

    HWND  hWnd,	// handle of window
    LPRECT  lpRect 	// address of structure for window coordinates
   );	


Parameters

hWnd

Identifies the window. 

lpRect

Points to a RECT structure that receives the screen coordinates of the upper-left and lower-right corners of the window. 



Return Value

If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE. To get extended error information, call GetLastError. 

See Also

GetClientRect, RECT 


========================


 ReleaseCapture  QuickInfo  Overview  Group

The ReleaseCapture function releases the mouse capture from a window in the current thread and restores normal mouse input processing. A window that has captured the mouse receives all mouse input, regardless of the position of the cursor, except when a mouse button is clicked while the cursor hot spot is in the window of another thread. 

BOOL ReleaseCapture(VOID)


Parameters

This function has no parameters. 

Return Value

If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE. 

Remarks

An application calls this function after calling the SetCapture function. 
Windows 95 only: Calling this function causes the window that is losing the mouse capture to receive a WM_CAPTURECHANGED message.

See Also

GetCapture, SetCapture 


========================


 SendMessage  QuickInfo  Overview  Group

The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately. 

LRESULT SendMessage(

    HWND  hwnd,	// handle of destination window
    UINT  uMsg,	// message to send
    WPARAM  wParam,	// first message parameter
    LPARAM  lParam 	// second message parameter
   );	


Parameters

hwnd

Identifies the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows. 

uMsg

Specifies the message to be sent. 

wParam

Specifies additional message-specific information. 

lParam

Specifies additional message-specific information. 



Return Value

The return value specifies the result of the message processing and depends on the message sent. 

Remarks

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, Windows switches to that thread and calls the appropriate window procedure. 

See Also

InSendMessage, PostMessage, SendDlgItemMessage 


========================


 ShowWindow  QuickInfo  Overview  Group

The ShowWindow function sets the specified window's show state. 

BOOL ShowWindow(

    HWND  hwnd,	// handle of window
    int  nCmdShow 	// show state of window
   );	


Parameters

hwnd

Identifies the window. 

nCmdShow

Specifies how the window is to be shown. This parameter can be one of the following values: 

Value	Meaning
SW_HIDE	Hides the window and activates another window.
SW_MAXIMIZE	Maximizes the specified window.
SW_MINIMIZE	Minimizes the specified window and activates the next top-level window in the Z order.
SW_RESTORE	Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_SHOW	Activates the window and displays it in its current size and position. 
SW_SHOWDEFAULT	Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application. An application should call ShowWindow with this flag to set the initial show state of its main window.
SW_SHOWMAXIMIZED	Activates the window and displays it as a maximized window.
SW_SHOWMINIMIZED	Activates the window and displays it as a minimized window.
SW_SHOWMINNOACTIVE	Displays the window as a minimized window. The active window remains active.
SW_SHOWNA	Displays the window in its current state. The active window remains active.
SW_SHOWNOACTIVATE	Displays a window in its most recent size and position. The active window remains active.
SW_SHOWNORMAL	Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when displaying the window for the first time.


Return Value

If the window was previously visible, the return value is TRUE. If the window was previously hidden, the return value is FALSE. 

Remarks

ShowWindow must be called only once per program with the WinMain function's nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the preceding list, instead of the one specified by the WinMain function's nCmdShow parameter. 
As noted in the discussion of the nCmdShow parameter, an application should call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use application startup information that affects how a window is displayed. For example, Program Manager specifies that applications start with a minimized main window. Win32-based applications also use the application startup information when calling ShowWindow for the first time and set nCmdShow to SW_SHOW. This behavior is designed for the following situations: 

·	Applications that create their main window by calling CreateWindow with the WS_VISIBLE flag set. 
·	Applications that create their main window by calling CreateWindow with the WS_VISIBLE flag cleared, and later call ShowWindow with the SW_SHOW flag set to make it visible. 



See Also

CreateProcess, CreateWindow, ShowOwnedPopups, STARTUPINFO, WinMain 


========================


 RECT  QuickInfo

typedef struct _RECT {    // rc 

    LONG left; 
    LONG top; 
    LONG right; 
    LONG bottom; 
} RECT; 
 

The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle. 

Members

left

Specifies the x-coordinate of the upper-left corner of the rectangle. 

top

Specifies the y-coordinate of the upper-left corner of the rectangle. 

right

Specifies the x-coordinate of the lower-right corner of the rectangle. 

bottom

Specifies the y-coordinate of the lower-right corner of the rectangle. 



Remarks

When RECT is passed to the FillRect function, the rectangle is filled up to, but not including, the right column and bottom row of pixels. This structure is identical to the RECTL structure.

See Also

FillRect, RECTL, SMALL_RECT 


========================


 POINT  QuickInfo

typedef struct tagPOINT { // pt 

    LONG x; 
    LONG y; 
} POINT; 
 

The POINT structure defines the x- and y- coordinates of a point. 

Members

x

Specifies the x-coordinate of the point. 

y

Specifies the y-coordinate of the point. 



See Also

ChildWindowFromPoint, GetBrushOrgEx, PtInRect, SetBrushOrgEx, WindowFromPoint 


========================


 WM_NCLBUTTONDOWN  QuickInfo  Overview  Group

WM_NCLBUTTONDOWN 

nHittest = (INT) wParam;    // hit-test value 
pts = MAKEPOINTS(lParam);   // position of cursor 
 

The WM_NCLBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. 

Parameters

nHittest

Value of wParam. Specifies the hit-test value returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For a list of hit-test values, see WM_NCHITTEST. 

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. 



Return Value

If an application processes this message, it should return zero. 

Default Action

The DefWindowProc function tests the given point to find out the location of the cursor and performs the appropriate action. If appropriate, DefWindowProc sends the WM_SYSCOMMAND message to the window. 

Remarks

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure. 

See Also

DefWindowProc, MAKEPOINTS, POINTS, WM_NCHITTEST, WM_NCLBUTTONDBLCLK, WM_NCLBUTTONUP
, WM_SYSCOMMAND 


========================


 WM_NCHITTEST  QuickInfo  Overview  Group

WM_NCHITTEST 

xPos = LOWORD(lParam);  // horizontal position of cursor 
yPos = HIWORD(lParam);  // vertical position of cursor 
 

The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. 

Parameters

xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the screen. 

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the screen. 



Return Value

The return value of the DefWindowProc function is one of the following values, indicating the position of the cursor hot spot: 

Value	Location of hot spot
HTBORDER	In the border of a window that does not have a sizing border
HTBOTTOM	In the lower horizontal border of a window
HTBOTTOMLEFT	In the lower-left corner of a window border
HTBOTTOMRIGHT	In the lower-right corner of a window border
HTCAPTION	In a title bar
HTCLIENT	In a client area
HTERROR	On the screen background or on a dividing line between windows (same as HTNOWHERE, except that the DefWindowProc function produces a system beep to indicate an error)
HTGROWBOX	In a size box (same as HTSIZE)
HTHSCROLL	In a horizontal scroll bar
HTLEFT	In the left border of a window
HTMENU	In a menu
HTNOWHERE	On the screen background or on a dividing line between windows
HTREDUCE	In a Minimize button
HTRIGHT	In the right border of a window
HTSIZE	In a size box (same as HTGROWBOX)
HTSYSMENU	In a System menu or in a Close button in a child window
HTTOP	In the upper horizontal border of a window
HTTOPLEFT	In the upper-left corner of a window border
HTTOPRIGHT	In the upper right corner of a window border
HTTRANSPARENT	In a window currently covered by another window
HTVSCROLL	In the vertical scroll bar
HTZOOM	In a Maximize button


Remarks

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure. 

See Also

DefWindowProc, GetCapture, MAKEPOINTS, POINTS 


========================

.

.

Quit = 1

--------------

Top Ten Reasons Not To Procrastinate:


Coming Soon...

Edited by - art sentinel on 06 August 2002  08:04:54
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Danilo.

HINT:
> Procedure XY2ClientArea()
> [..snip..]

See: mapwindowpoints_(hWndFROM, hWndTO, lpPOINTs, cPOINTs)

cya,
...Danilo

(registered PureBasic user)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Art Sentinel.

Danilo, thank you for your hint! I read before though that MapWindowPoints was a slightly slower function? (It uses more system resources?) The article I read it from never explained themselves very well. What do you think? Did you do tests?

ScreenToClient_(hwnd, lpPoint) is another alternative, but I wanted demonstrate the basic math routines for those learning to 'think programming'.

Thank you again for your helpful hint. I honestly appreciate it. :)

Take care.


- Art Sentinel
http://www.artsentinel.net


--------------

Top Ten Reasons Not To Procrastinate:


Coming Soon...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Franco.

Good work Art!

One little hint.
I don't know if you know that normally you don't have to build your own POINT and RECT Structures.

A good thing about PureBasic is, that you can use the API Structures like:

Global myPOINT.POINT
Global myRECT.RECT

They are already declared internally for nasm.

Nice to see that somebody has enough time to do such a tutorial.
Keep going!


Have a nice day...
Franco

Sometimes you have to go a lonely way to accomplish genius things.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Art Sentinel.

Thank you immensely Franco! :)

I may be weird, but I honestly love learning new things--especially about things as enjoyable as programming in PureBasic. To be honest with you, I would have written the above tutorial the same way, even if I had been armed with the information you shared with me. (The above way is still probably a little better to illustrate what a structure is to those new to that concept.)

However, you can be absolutely positive that the next structure-based WinAPI tutorial I write will use your excellent tip. I hadn't realized that PB stores internally all the API Structures. Using the API in PB was already very easy compared to C or Visual Basic. Having the structures already predefined makes it even easier than I would have imagined! :)

Thank you, my generous friend. That is one piece of information you can be certain I won't be forgetting.

Take care.


- Art Sentinel
http://www.artsentinel.net


--------------

Top Ten Reasons Not To Procrastinate:


Coming Soon...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Kendrel.

Very nice...

Thumbs up for that!

So this is the 3rd Tutorial? Where are the two others?
Would be kinda cool if ppl could download that stuff!

regards,

Kendrel
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Paul.

Thanks to Art, the tutorials are available on the Resources Site...
http://www.reelmediaproductions.com/pb
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by El_Choni.

Amazing, I had never seen a Drag Window

Thanks for your tut!

El_Choni
Post Reply