In child window of my application, I have placed one single line edit control named as sle_name. Its tab order is 1.
Below that control I have placed DataWindow having formatted as free form style.
When I run the app, if my focus is in sle_name, and I click on sle_name then rbuttondown event is triggered. Then I move my focus to DataWindow(dw_account). Once I got focus on dw_account and then if I try to click on sle_name, my focus is not moving on sle_name and neither I can run rbuttondown event on sle_name.
What is the reason for this problem?
One more thing: when I start this window my focus in set in sle_name, from that control if I press tab key then my focuse moves to dw_account and if I press again shift+tab then my focus is moved back to sle_account.
But if I try to set focus from dw_account to sle_account using mouse pointer it is not moving focus.
What is the reason behind this behaviour?
I had the same behavior in a child window.
It was fixed when disabled the 'ControlMenu' and 'TitleBar' properties in the window. (It's so strange).
Hope it helps
Juanma
This isn't natural behaviour, so the cause is likely something you've scripted. Depending on your architecture, the culprit code could be a number of places (e.g. framework objects). If this were my problem, I'd run with the PBDEBUG trace turned on (a System Option in the IDE, or /PBDEBUG on the command line after the deployed EXE name), and see what is firing when you try to move back to the SLE.
I'd also be using PBL Peeper to see the trace and the code side-by-side, so it's easier to see what code is being executed (the trace only shows you script name and line number).
Good luck,
Terry.
you must have to create the event ID pbm_lbuttonup, with the same parameter as rbuttondown event. Then in the code you write this.setfocus()
Related
I'm trying to automate a many clicking process, just to narrow it to the user input.
I encountered problems in controlClicking interface elements, which seems not to be standard Windows GUI elements.
When pointing them with WinSpy they don't appear as separate buttons, but I can point the whole child Window which is drawn in the main program window.
As on pic1, I pointed the whole window and I can find each tab/button by it's text inside and on pic2 I can inspect the ClassNN of that element and it's ID.
As far as clicking other buttons in the main menu bar of the program works, a simple:
ControlClick, ClaTab_01000000H26, WindowName
doesn't work. I think during the day, and many possibilities I tried, I could ControlClick the above button by pointing it with its ID, but that ID changes every instance. I could confirm that tomorrow if it works by ID.
Of course I tried SetControlDelay -1 and ,NN option. But don't take that for granted, I can try any of your suggestions tomorrow.
Both tabs marked with purple color, are to find in the Windows->SiblingWindows tab. I really don't want using x,yCoords (that actually work), but I need the script to be as reliable as possible.
So my questions are:
Am I missing something or you have any suggestions how to click that elements?
Is it correct, that no matter how deep the child windows get (one has buttons to open another on top of it), all the time the WinName stays the same pointing to the main program ***.exe?
Could you provide an example from the web or yours, to find an element's ID by providing the text attached to the button (pic1-red line and also pic2 in "text")?
I also cannot maximize the child window. Double clicking it works, but I can't find the appropriate ClassNN of the window to call.
Could you provide an example, how to use the Messages tab? I assume, if I find the button as on the pictures, I could send a message with controlClick and see if there's a reaction?
1.Ugh. I found the solution, which is awesome, but a little frustrating that with a bit of luck I tried another aproach that's not that logical for a newbie like me:
instead:
ControlClick, ClaTab_01000000H6, ahk_class ClaWin01000000H_2,,,, NA
it's just
ControlFocus, ClaTab_01000000H6, ahk_class ClaWin01000000H_2,,,, NA
2._Yep. One child window creates another and another and another, but winTitle stays the same. In my case:
ahk_class ClaWin01000000H_2
3._Code below returns the handle/ID of the element you specify. Change ClaTab and ClaWin to your chouice.
ControlGet, OutputVar, hwnd,, ClaTab_01000000H1, ahk_class ClaWin01000000H_2
MsgBox, %OutputVar%`
Probably to be continued.
I highly recomend to both use
WinSpy https://www.autohotkey.com/boards/viewtopic.php?t=28220
SimpleSpy https://www.the-automator.com/downloads/simple-spy/
First one has lots of useful information and the window tab provides information of hidden buttons/windows. Second one in a more clear way indicates the parent window and its class.
I originally had code that set the focus to the first widget in a dialog, in the onInit method. But there were problems with it: if I pressed TAB, indeed focus moved to next control (wxTextCtrl), which got the blue 'focus' color, but the 'focus' color/highlight was not removed from previous focus widget. So now it looked like both first and second control had focus at the same time...
When cycling manually (by pressing TAB) full circle (till last control and then wrap around to the first), suddenly all worked well. That is, when moving focus from first control to next one, the first visually lost focus (blue color was removed) as it should. From now on, only one item had the focus color/highlight.
So instead of setting focus on the first control, I tried a different approach: I set the focus to the last control in the dialog, which is always the OK button. Next, I want to emulate programmatically that a TAB is pressed and received by the dialog. So I wrote this (inside Dialog::onInit):
m_buttonOK->SetFocus();
wxKeyEvent key;
key.SetEventObject(this);
key.SetEventType(wxEVT_CHAR);
key.m_keyCode=WXK_TAB;
ProcessWindowEvent(key);
Now the focus indeed moves away from the OK button, but it does not wrap around to the first control.
Only when I manually press TAB after the dialog opened, the first item gets focus.
Question: why does this wrapping around to set focus on first widget not work with the code shown above?
First of all, your initial problem is almost certainly related to not calling event.Skip() in one of your event handlers, see the note in wxFocusEvent documentation.
Second, you can't send wx events to the native windows, they don't know anything about it. In this particular case you can use wxWindow::Navigate() to do what you want, but generally speaking what you're doing simple can't, and won't, work reliably.
So I have looked through existing answers tagged with dockpanel-suite and have not found what I am looking for (as I type this, it is also not appearing in the Similar Questions area). For starters, note that I am NOT asking about saving and restoring the entire Workspace.
So here is the scenario. I have a graphical window (we will call it "Timeline") that is added upon user request. When it is added, it is automatically docked to the bottom-most area of the main form. The user then takes the Timeline window and redocks it somewhere else (could be docked to an edge, or within another docking pane) and changes its docking behavior (floating, auto-hide, tab, etc.).
A demonstrable example is in Visual Studio. If you have the Solution Explorer on a tab within an docked pane on the right and close Solution Explorer, you can go to View -> Solution Explorer and bring it back up again, and it restores to the correct location.
Now the user closes the Timeline window entirely by hitting the [x] on its pane, and in the future, they request to add it to the application again. I want to bring it back in the last dock state and position it was in when it was last closed.
Now, I appear to be able to catch the closing of the pane with the ContentRemoved event, but in there e.Content.DockHandler.Pane, e.Content.DockHandler.PanelPane and e.Content.DockHandler.FloatPane are all null so I have no obvious way to get the previous dock geometry. e.Content.DockHandler.DockPanel is valid, but it is the parent/root docking panel, and calling SaveAsXml(...) does nothing for me because it would get the entire workspace.
Even if I were able to capture it here, information I need. However, I do not appear to be able to simply call LoadFromXml(...) on anything either.
If I try to do it before the DockContent object is added to the DockPanel, DockHandler.DockPanel member is null, so I appear to have no place to restore the XML into, even if I was able to get it.
There are no other events hanging off of DockPanel that seem to be able to help me here.
So - is there a way to do this, and what is the correct way to do it? I want to make sure I am not barking up the wrong tree with trying to capture the dock information as XML when closed and restore it later.
I have toyed with the idea of not actually closing the window but just undocking and hiding it, but have not explored that very far yet. Same with hooking the DockChanged event, but it does not seem to fire on the DockContent objects being docked/floated/etc. and I am not sure why.
Also the solution needs to be robust enough so that I can correctly handle scenarios such as if the last docking parent no longer exists. For example, if it was docked as a tab somewhere, but now that parent window (containing the tabs) has also been closed. I do not know if LoadFromXml, presuming it is the right way to do, is robust enough to handle this scenario, as I have not been able to test it yet.
If I understand the question, what I do is to trap the Closing or FormClosing event, .Hide() the form and set e.Cancel = true. If you are using DockContent, then there is a HideOnClose() that does the work for you. Then when you want to "re-open" the window, you simply use an empty .Show(), and it will Show right where it was when you "closed" it.
As far as saving if the last docking parent no longer exists, I agree with Lex Li, that will take a hack.
When you press F2 to edit a filename in Windows Shell, there is a limited set of editing keys that is understood - e.g. CTRL+Arrow Keys, Home, End, CTRL+X. For example, when you type CTRL+Right Arrow, the cursor will stop right after a dash, but will not stop at a period. Are these actions customizable, and if so, how?
Any additional information not directly related but which you feel might help the topic will also be appreciated.
You can set a custom word-break procedure for your edit control using EM_SETWORDBREAKPROC; EditWordBreakProc is the corresponding callback function that the OS calls when it needs to find where a word break occurs.
From the docs:
Either a multiline or a single-line edit control might call this function when the user presses arrow keys in combination with the CTRL key to move the caret to the next word or previous word.
The key combinations themselves are not directly customizable, and for a good reason -- so that the user experience is uniform across all applications. Of course, you could subclass the edit control and handle keyboard messages yourself but I guess that's not the point here.
The Windows version matters, but in general this behavior is baked into SysListView32, the native list view control. No, keyboard handling is hard-baked. Subclassing the control is technically possible, just not practical since it lives inside Explorer.exe. And having no clue where the caret is located inside the label, there are no messages for it.
By "Windows Shell" I assume you mean Windows Explorer, but the answer is likely the same no matter what program you are talking about.
Explorer simply creates an EDIT control and moves it into position. The editing behavior comes from this stock system control, plus whatever additional logic Explorer adds to its own instance of it.
While you can easily alter the behavior of an EDIT control that belongs to a thread in your own process, doing so in another process requires a global hook. We will stipulate that you understand the amount of work involved in doing a global hook correctly, and which will function in both x86 and x64 environments.
You cannot directly interfere with the behavior of an EDIT control in another process with WH_CALLWNDPROC, but you can use WH_CALLWNDPROCRET to observe keyboard messages, check that the window is and EDIT control, check that the EDIT control belongs to Explorer, and then knowing precicesly how the EDIT control responded to that keyboard event, do something additional like backing up to that period.
Or maybe you could use a WH_CBT hook to monitor HCBT_CREATEWND and subclass the EDIT control each time it gets created.
The effort is probably not worth the benefit.
It's a longshot that anyone can help with this, but here goes. I inherited a VB6 app with a Janus GridEX control. It iterates through records, and is editable. Problem is, if I edit a cell and hit the button to go to the next record, the change is applied to the next record, not the one I was editing. It's like, I need it to finish up the edit before going to the next record. I've had this sort of problem before in VC++, and sometimes you have to "KillFocus" on the control you're on or something. I just don't know what to do here. I tried sending a carriage return, since if you return out of the edit cell, it works, but sending a carriage return manually doesn't work. What's the secret?
Is your grid bound or unbound?
It's hard to tell from your description, but I imagine that if your are having this problem then it's probably bound.
As the other answer asked, is the button the RecordNavigator that is built into the control or is it a separate button? The reason I bring this up again, is that I have seen issues in the VB6 applications I support where a toolbar will often intercept and interfere with how the JanusGrid should work.
To get around this limitation, I have added the following code in the click handler of any toolbars where there is also a JanusGrid control on the form.
If jsgxYourGridName.EditMode = jgexEditModeOn Then jsgxYourGridName.Update
This way any changes are immediately applied to the current row.
If this does not help, then I have also seen problems where the recordset that is bound to the grid gets out of sync with the internal recordset in the grid. You can check this by comparing the bookmark of the grid to the bookmark of the recordset.
Ie. mrsYourRecordset.Bookmark = jsgxYourGrid.ADORecordset.Bookmark
At one point I may have also used something like this.
jsgxYourGrid.ADORecordset.Bookmark = jsgxYourGrid.RowBookmark(jsgxYourGrid.RowIndex(jsgxYourGrid.Row))
Finally you can try setting a breakpoint in the BeforeUpdate, RowColChange and/or AfterColUpdate events of the grid, to see what record the grid is really on when clicking on the button.
It depends whether the button is internal to Janus GridEX or not. If it internal then just about the only thing you can do is look at the events the control exposes to see if there a sequence that can let you know that this problem occurs. Then you can try to take corrective action by restoring the row you moved to and put the edit in the row you left.
If the button is external to Janus then you can use the debug mode to trace sequence of statement that control the transfer of focus to the next row. It could be something out of order or a side effect of the particular sequence of commands. I have run into both with different controls.
Remember that you can edit while in debug mode so you can try different approaches and test until you find one that works.