Announcement

Collapse
No announcement yet.

Simulate click on a treeview in code

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • BOB MECHLER
    replied
    Much safer to use this than what I was doing.

    Thanks,

    Bob Mechler

    Leave a comment:


  • Michael Mattias
    replied
    First treeview item?

    TreeView_GetRoot (hTreeView)

    Leave a comment:


  • BOB MECHLER
    replied
    Latest attempt:

    The following works on resolutions from 800x600 to 1280x1024
    The Else code clicks the first treeview item if there was no previous
    session since the last reboot.

    To center the click just used the client area of the selected treeview
    item's RECT. Had to also account for the non-client area (caption bar etc).

    Code:
         'Select the treeview item last used
         'Get it's RECT values
         'Get total size of DIALOG
         'Get client size of DIALOG
         'Get non-client y axis value
         'Convert to pixels
         'Get location of top left treeview control
         'Convert to pixels
         'Set curpos at left edge of dialog plus left edge of tree view 
    plus center of items
         'also set y axis to top of dialog plus top of treeview plus 
    non-client area + center of item.
    
    'hMenu&(SCR) SCR identifies the menu 1-19 hMenu& is the handle to the 
    item when it was first inserted.
        IF hMenu&(SCR) <> 0 THEN
          TreeView_SelectItem hTree&(1),hMenu&(SCR)
          TreeView_GetItemRect hTree&(1),hMenu&(SCR),rc,%True
          DIALOG GET SIZE hdlg TO tot_x&,tot_y&
          DIALOG GET CLIENT hdlg TO cli_x&,cli_y&
          DIALOG UNITS hdlg,tot_x& - cli_x&,tot_y& - cli_y& TO PIXELS non_client_x&,non_client_y&
          DIALOG GET LOC hdlg TO MOUSE_X&,MOUSE_Y&
          DIALOG UNITS hdlg, MOUSE_X&,MOUSE_Y& TO PIXELS P_MOUSE_X&,P_MOUSE_Y&
          CONTROL GET LOC hdlg,%ID_TREE1 TO TV_X&,TV_Y&
          DIALOG UNITS hdlg, TV_X&,TV_Y& TO PIXELS P_TV_X&,P_TV_Y&
          SetCursorPos P_MOUSE_X& + P_TV_X& + (rc.nLeft + rc.nRight)/2, P_MOUSE_Y& + P_TV_Y& + non_client_y& + (rc.nTop + rc.nBottom)/2
        ELSE
           ' click first item in treeview
           DIALOG GET SIZE hdlg TO tot_x&,tot_y&
           DIALOG GET CLIENT hdlg TO cli_x&,cli_y&
           DIALOG UNITS hdlg,tot_x& - cli_x&,tot_y& - cli_y& TO PIXELS non_client_x&,non_client_y&
           DIALOG GET LOC hdlg TO MOUSE_X&,MOUSE_Y&
           DIALOG UNITS hdlg, MOUSE_X&,MOUSE_Y& TO PIXELS P_MOUSE_X&,P_MOUSE_Y&
           CONTROL GET LOC hdlg,%ID_TREE1 TO TV_X&,TV_Y&
           DIALOG UNITS hdlg, TV_X&,TV_Y& TO PIXELS P_TV_X&,P_TV_Y&
           SetCursorPos P_MOUSE_X& + P_TV_X& + 100, P_MOUSE_Y& + P_TV_Y& + non_client_y& + 9
        END IF
        mouse_event %MOUSEEVENTF_LEFTDOWN OR %MOUSEEVENTF_ABSOLUTE, 0, 0, 0, 0
        mouse_event %MOUSEEVENTF_LEFTUP OR %MOUSEEVENTF_ABSOLUTE, 0, 0, 0, 0
    Works for any resolution (at least 800x600 through 1280x1024) or any position on screen
    Last edited by BOB MECHLER; 12 Nov 2007, 08:41 AM.

    Leave a comment:


  • Michael Mattias
    replied
    FWIW... TreeView_HitTest (TVM_HITTEST message ) will tell you if you if a point is on an item or in the 'no man's land' of the control. You can test this on WM_NOTIFY/NM_CLICK if you want to know if the user clicked on an item or elsewhere.

    Leave a comment:


  • Michael Mattias
    replied
    >Dark blue with white letters leaves no doubt...

    That requires the treeview control have the keyboard focus, otherwise you get that kind of "pale brown on white" which means that's the selected item but the control does not have the keyboard focus. (You get the same effect with the listview control).

    I used to do a lot with the treeview control, that is until I started trying to put "many many" (tens of thousands) of nodes in it. At that point the "load time" and "unload time" become just too much to tolerate. Since there is no "virtual mode" for the treeview control as there is with the listview control, I ended up writing my own virtual treeview control.

    MCM

    Leave a comment:


  • BOB MECHLER
    replied
    True.

    I really should get to know more about the treeview control and work it properly. As anyone would suspect, I've only started working with the treeview control about the time of my first post for help. As time goes on I'm using more and more of the SDK style of programming to redo the look and feel of our application. With the SDK it's wide-open what you can do. Just haven't worked with the treeview long enough to do more than fill a couple of two level treeviews and search through the nodes for text that matches the data statements I have for the menu system and then determine the right program to launch.

    Just clicking anywhere in the treeview except directly on an item does what I want. The item is already dimly highlighted to the last item (menu) selected when it comes back from running another program. I had to leave the background of the treeview white even to see it. On some monitors it can't be seen at all, which is the reason I wanted the effect caused by the color scheme when it's been clicked. Dark blue with white letters leaves no doubt.

    I could request the code for getting the co-ordinates of a point just to the right of the 4th item in a treeview but not where a mouse click would select that item, just change focus to the control so the currently selected item would turn to a focused color scheme but I won't. That would be laziness on my part.

    Thanks,

    Bob Mechler

    Leave a comment:


  • Michael Mattias
    replied
    >SetCursorPos P_MOUSE_X& + 320, P_MOUSE_Y& + 120

    320? 120?

    Perhchange is the treeview control located at 320,120?

    If so, then this code will fail if the user is using a different monitor resolution.. because DIALOG UNITS will not be the same number of PIXELS under that different resolution.

    FWIW, you might also try selecting the treeview item of interest (as above), then explicitly SetFocus to the treeview control. Doc says...
    TVIS_SELECTED
    The item is selected. Its appearance depends on whether it has the focus. The item will be drawn using the system colors for selection
    (TVIS_SELECTED state will be set when you select the item)

    You may still have to force a redraw to get the highlighting. For as much time as you seem to have spent on this, it seems a shame to settle for less (select + highlight the first node) than you originally wanted (select and highlight any node).

    MCM

    Leave a comment:


  • BOB MECHLER
    replied
    Since by trial and error I found exactly where the place was that I needed to simulate a mouse click in the treeview control but not on an item, the following code works anywhere the dialog happens to be, even on a two monitor system.

    Code:
        '
        'click in client area of first treeview to get selected item to turn blue
        '
        DIALOG GET LOC hdlg TO MOUSE_X&,MOUSE_Y&
        DIALOG UNITS hdlg, MOUSE_X&,MOUSE_Y& TO PIXELS P_MOUSE_X&,P_MOUSE_Y&
        SetCursorPos P_MOUSE_X& + 320, P_MOUSE_Y& + 120
        mouse_event %MOUSEEVENTF_LEFTDOWN OR %MOUSEEVENTF_ABSOLUTE, 0, 0, 0, 0
        mouse_event %MOUSEEVENTF_LEFTUP OR %MOUSEEVENTF_ABSOLUTE, 0, 0, 0, 0
    In a treeview that doesn't have the focus the selected item is a very faint default dialog background color. This method sets it to blue background and white lettering as it is getting the focus. In standard programs I understand a simple Control Set Focus would have worked but in my code the cursor is in a field that validates input. Simulating this mouseclick before going into the field puts the focus where I want it to be. The user can then click on the field from there or use the treeview.
    I actually have the same message pump for each textbox on my screen one at a time (using dialog doevents and trapping function keys and enter to exit the message loop and go to the next control). All my buttons,listviews, listboxes and clickable labels do their work through the dialog callback. It was just easier to do than subclassing every single textbox for specific functionality and validation. I do format and validation checking as I leave the field and then re-enter it if something isn't right, giving an appropriate help message box.

    At least one control is always in a message pump at all times. Clicking the X or issuing a DIALOG END message in a call back exits the message pump and then I direct the program flow to my shutdown procedure in which I close files, pull up print preview and/or decide which program to run next or back to my main menu.

    Bob Mechler
    Last edited by BOB MECHLER; 10 Nov 2007, 10:22 AM.

    Leave a comment:


  • BOB MECHLER
    replied
    That last clue I like. I overlooked the TreeView_GetItemRect function. That should do the same thing as I originally tried but do it no matter where the dialog is even on a two monitor system. Thanks

    Bob Mechler

    Leave a comment:


  • Michael Mattias
    replied
    I think forcing a redraw of the control will give you the highlighting.

    And if you want, you can even move the mouse cursor to the selected item: use the Treeview_GetItemRect function, convert any point within the returned RECT to screen coordinates and then SetCursor().

    MCM

    Leave a comment:


  • BOB MECHLER
    replied
    When I use the mouse method I get the node highlighted in blue with white letters. When I use any other method it just shows selected but a default windows background color.

    Bob Mechler

    Leave a comment:


  • BOB MECHLER
    replied
    So TreeView_SelectItem is the same as clicking on it. Makes sense. Just have to make sure I have the right parameters for the node I want.

    Thanks,

    Bob Mechler

    Leave a comment:


  • Michael Mattias
    replied
    >The SetCursorPos however seems to be relative to the desktop instead of the dialog.

    Um, that's because that is what it is supposed to do:
    The SetCursorPos function moves the cursor to the specified screen coordinates
    You can use the ScreenToClient and ClientToScreen functions to convert between screen (desktop) coordinates and "client area coordinates."

    MCM

    Leave a comment:


  • Michael Mattias
    replied
    Just select the node you want to "click on".

    see: Treeview_SelectItem macro or TVM_SELECTITEM message

    When you call the TreeView_SelectItem macro, the control's parent window receives the TVN_SELCHANGING and TVN_SELCHANGED notification messages

    Leave a comment:


  • Adam J. Drake
    replied
    If you know which node you want to go back to, based on item handle - you can use the Treeview_Expand MACRO, or the send the %TVM_EXPAND message.

    Leave a comment:


  • BOB MECHLER
    started a topic Simulate click on a treeview in code

    Simulate click on a treeview in code

    I have two treeviews. One shows a two level structure. The other is built on the fly using data statements based on the node clicked in the first treeview. When the program initially presents the left tree view is populated automatically but the right does not. What I want is a way to click the first menu node on treeview one to crank up the code to build treeview 2.

    So far the only method has been trial and error use SetCursorPos and the Mouse_event
    Code:
    SetCursorPos 480,290
    mouse_event %MOUSEEVENTF_LEFTDOWN OR %MOUSEEVENTF_ABSOLUTE, 480, 290, 0, 0
    mouse_event %MOUSEEVENTF_LEFTUP OR %MOUSEEVENTF_ABSOLUTE, 480, 290, 0, 0
    This works ok, it is placed in a non active area of the treeview and when it fires it selects the first node by default and voila the TVN_SELCHANGED event is fired, the second treeview shows and the first item is drawn as selected.

    The SetCursorPos however seems to be relative to the desktop instead of the dialog.

    Is there a way using %NM_CLICK or something to programmatically click on demand any particular node in the first treeview to trigger the second treeview build.

    When coming back to the menu from a called program I want a programmatic click to click the last menu node on the left that I used going to the program.

    Bob Mechler
Working...
X