May 16, 2024, 12:27:11 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


how can i drag a button ?

Started by splakidas, April 10, 2007, 02:18:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

splakidas

is there any simple way to drag my buttons and change position after i draw them ?  ???

sapero

Subclass the button and send a message to button's caption$include "windows.inc"
DIALOG d1
INT g_buttonproc
CREATEDIALOG d1,0,0,300,202,0x80CA0880,0,"Caption",&d1_handler
CONTROL d1,@SYSBUTTON,"drag me",96,63,70,20,0x50010000,1000
domodal d1

SUB d1_handler
SELECT @MESSAGE
CASE @IDINITDIALOG
g_buttonproc = _SetWindowLong(GetControlHandle(d1, 1000), GWL_WNDPROC, &DragDropCtlProc)
CASE @IDCLOSEWINDOW
CLOSEDIALOG d1,@IDOK
ENDSELECT
RETURN
ENDSUB

sub DragDropCtlProc(hwnd:int,msg:int,wparam:int,lparam:int),int

if (msg=WM_LBUTTONDOWN) /* and dragging alloved */
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0)
return 0
endif
return _CallWindowProc(g_buttonproc, hwnd, msg,wParam,lParam)
endsub

splakidas


splakidas

just put  a second button
CONTROL d1,@SYSBUTTON,"drag me",96,63,70,20,0x50010000,1000
CONTROL d1,@SYSBUTTON,"drag me2",196,163,70,20,0x50010000,1001

and subclassed also button 2
SUB d1_handler
SELECT @MESSAGE
CASE @IDINITDIALOG
g_buttonproc = _SetWindowLong(GetControlHandle(d1, 1000), GWL_WNDPROC, &DragDropCtlProc)
g_buttonproc = _SetWindowLong(GetControlHandle(d1, 1001), GWL_WNDPROC, &DragDropCtlProc)
CASE @IDCLOSEWINDOW
CLOSEDIALOG d1,@IDOK
ENDSELECT
RETURN
ENDSUB


works super.


Sapero how easy is it to resize one of them ?

sapero

I would create the button as child of a another child window (like static control), 1-2 pixels wider and higher than the button, then draw a sizing rectangle on this static control if the button has keyboard focus, detect mouse moving to change the cursor in same way as in dialog editor, and simply resize the static and button if the mouse is moving while the left mouse button is down.
To do so, just create a static control 82x22, and button as child of this static at 1,1 80x20. Subclass this static control to be able to respond to mouse moving. Also subclass your button to detect the focus and notify the static control about.

Pseudo code for static control:
WM_NCHITTEST: retrun HTCLIENT, only for static/group controls you need to handle this message
WM_MOUSEMOVE: if (button has focus) and (left mouse button is up) then SetCursor(CursorPosToCursorType(x,y))
// where CursorPosToCursorType returns up+down arrow if 'mouse' is over upper or lever border...
if (button has focus) and (left mouse button is down) - resize/move the static and resize the button
WM_SETFOCUS - draw or remove black border from static control, it enables or diables cursor changes inside WM_MOUSEMOVE. You'll need to save previous static position and size (rectangle) to propertly move and resize it.

Pseudo code for button control:
WM_SETFOCUS - notify the static control that you got or lost the focus (draw/remove the sizing rectangle)

If your familiar with MASM, you can study the ResEd source for this (resource editor)
Of course you can create this static control only if the button got focus, so you can change the parent of button to this static control, then move the button back and destroy this static control, if the button lost focus.

Another possiblity: change button style - add or remove WS_SIZEBOX or WS_THICKFRAME:
CONTROL d1,@SYSBUTTON,"drag me",96,63,70,20,0x50010000 | 0x40000,1000

splakidas


LarryMc

Quote from: sapero on April 10, 2007, 06:44:34 PM
I would create the button as child of a another child window (like static control), 1-2 pixels wider and higher than the button, then draw a sizing rectangle on this static control if the button has keyboard focus, detect mouse moving to change the cursor in same way as in dialog editor, and simply resize the static and button if the mouse is moving while the left mouse button is down.
To do so, just create a static control 82x22, and button as child of this static at 1,1 80x20. Subclass this static control to be able to respond to mouse moving. Also subclass your button to detect the focus and notify the static control about.
Will this technique work for any control?
Quote from: sapero on April 10, 2007, 06:44:34 PM
Pseudo code for static control:
WM_NCHITTEST: retrun HTCLIENT, only for static/group controls you need to handle this message
WM_MOUSEMOVE: if (button has focus) and (left mouse button is up) then SetCursor(CursorPosToCursorType(x,y))
// where CursorPosToCursorType returns up+down arrow if 'mouse' is over upper or lever border...
if (button has focus) and (left mouse button is down) - resize/move the static and resize the button
WM_SETFOCUS - draw or remove black border from static control, it enables or diables cursor changes inside WM_MOUSEMOVE. You'll need to save previous static position and size (rectangle) to propertly move and resize it.

Pseudo code for button control:
WM_SETFOCUS - notify the static control that you got or lost the focus (draw/remove the sizing rectangle)

Of course you can create this static control only if the button got focus, so you can change the parent of button to this static control, then move the button back and destroy this static control, if the button lost focus.

Another possiblity: change button style - add or remove WS_SIZEBOX or WS_THICKFRAME:
CONTROL d1,@SYSBUTTON,"drag me",96,63,70,20,0x50010000 | 0x40000,1000
do you have any "actual" code samplke for all of that, that you would be willing to share?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

March 08, 2008, 10:08:31 AM #7 Last Edit: March 08, 2008, 10:18:42 AM by sapero
Try the arrached source. It creates some different controls, let you resize and move them, and aligns control position and size to 2-pixels.
It is not perfect, can be better.

KILLFOCUS handler is very primitive: hides and shows the control. I've not found better way to 100% redraw the control.

LarryMc

AWSUME!!!!!!!!!!!!! ;D ;D ;D

Of course initially it wouldn't compile and had a TON of errors. ???

After I downloaded your NEW windows.inc stuff it worked great.  :-[

The example was EXACTLY what I was looking for. ;D

You the man, Sapero!!!!hanks again,

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

the new windows.inc stuff is a lot more complicated looking than the shipped "windows.inc"

My question is that if I create a lib file that has the $include "windows.inc" statement in the lib source file will the user of the distributed lib also have to have the new windows.inc setup inoder to be able to use the lib?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Larry,
Once you make a .lib it is compiled, just machine code, no references to the include files are part of it.  The same as making a DLL or .exe

Paul.
Ionic Wind Support Team

LarryMc

thanks,

Life is great then!

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

March 11, 2008, 09:24:31 PM #12 Last Edit: March 11, 2008, 09:26:06 PM by Larry McCaughn
sapero,
playing with the sample code from above.

ran into a problem.
Here's what I CAN do:
left-click to select any of the controls and watch focus changed from control to control
right click while a control has focus and have a content menu popup.

Here's what I can not do:
Have a control selected (like above) and left click on the dialog (not on a control) and have the selected control automatically lose focus and have focus switch to the dialog itself.

I tried variations on this in the main dialog handler:
case  WM_LBUTTONDOWN
   if GetFocus()<> d1.hwnd
      SENDMESSAGE(GetFocus(), WM_KILLFOCUS, 0,0)
   endif
   _setfocus(d1.hwnd)


Am am I missing something entirely?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

I've gotten closer to making it work:

case  WM_LBUTTONDOWN
   if GetFocus()<> d1.hwnd
      setfocus(d1,1012)
   endif

where id 1012 is a blank @static located in the bottom left corner of the dialog and is 1x1 pixels
and it is not sub-classed like all the other controls

so, when I left-click outside a sub-classed control that currently has the focus the drag box will go away and I get the proper context menu to appear.

BUT
The sub-classed contextmenu routine(which looks like this:)
case WM_CONTEXTMENU
   ' create custom menu (for any control)
   wParam = CreateMenu(1)
   APPENDMENU(wParam,"Properties",MF_STRING,10000)
   APPENDMENU(wParam,"Delete",MF_STRING,10001)
   select TrackPopupMenu(wParam, TPM_RETURNCMD, LOWORD(lParam), HIWORD(lParam), 0, hwnd, 0)
      case 10001
         destroywindow(hwnd)
      case 10000
         showdialog d2
   endselect
   DestroyMenu(wParam)
   return 0

responds immediately (one-click) if I pick delete
but I have to click twice to get it to show the dialog.

Any ideas?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

1. In the WM_LBUTTONDOWN handler of the dialog, call _SetFocus(0), or set the focus to the invisible control
2. Because every CASE calls SELECT.
Save TrackPopupMenu return value in free variable then pass it to SELECT.

LarryMc

As usual, right on target.

Thanks Sapero

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

sapero

In the "drag" source file you posted above there is a line$define LPFNPROP "A8VD76"

Is there something specific about "A8VD76" or is that purely arbitrary and can be replaced with anything I want?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

This is a random string, typed by my fist ;D

LarryMc

My understanding is that it just has to be unique; right?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

April 07, 2008, 06:35:50 AM #19 Last Edit: April 07, 2008, 06:54:19 AM by Larry McCaughn
Sapero,

Ran into a problem I can't resolve.

I'm using the dragging routines you posted for me in the project I'm working on..

All the sudden the resizing of my edit control and my listbox control is acting weird.

Regardless of what size I create those 2 controls once I resize to larger than 110 x 25 they will not allow themselves to be resized to a size smaller than that even if they were created at a smaller size.

All the other controls resize as you would expect them to.

All the controls use the same subclassing and resizing routine.

You're example works fine by itself.

I'm not absolutely sure but I'm almost sure the 2 problem controls worked okay before I upgraded to 1.6/1.6.1
but I might be mistaken.

Got any ideas.

Almost forgot, the form that the controls are children of is also subclassed and has the dragging but the routines are copied and renamed just for the form.  Don't know if that makes any difference or not.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

It makes no difference, the compiled code does not know about function names.
In the MyControlProc() function try to block unprocessed messages (but selected only) - I did so to find why the static control did not allow me to resize it.

sub MyControlProc
  select
    case ...
    case ...

   ' add this
    default
      print hex$(uMsg)

Lookup the message in winuser.inc and if you think a printed 'hex' message can be the cause (like WM_NCLBUTTONDOWN), add new case and let it eat the message by returning zero, or better DefWindowProc (while CallWindowProc will forward this message to the control):
sub MyControlProc
  select
    case ...
    case ...

    ' messages to hide from subclassed control - call the default handler
    case WM_NCLBUTTONDOWN
    case& 0xSOMETHING
      return DefWindowProc(hwnd, uMsg, wParam, lParam)

    ' messages to eat - cancel this message
    case WM_**
    case& 0xSOMETHING2
      return 0


The string assigned to LPFNPROP can be any, but remember to not change already used by EBasic library strings like "LPFN", BBRUSH, BGRND, FGRND... (use EnumProps api to enumerate all them)

LarryMc

I ate all the messages that were coming through and no improvement.

Any other suggestions?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library