Experts: InputResizer: edit indicator and EA settings comfortably - page 2

 

symr:

- Maximize window wont work if u close it when its maximized and than reopen it
- The code not working properly in multi monitor systems, because the GetWindowRect returns negative values eg.: {-1127, 371,-553,679} sorry for that, NVM, it's my fault, working great with multiple mons...
- Sometimes some version of MT got a localization bug, and some button not always got a same caption (eg.: Cancel - (hungarian : "Mégse"))
- i think try to get a ControlID via GetControlID API and we wont need to set the localization button captions. MT doesnt shuffle control IDs.

Hi! I'm a bit confused.

- Everything works fine with maximized windows for me since the last fix (the bug with wrong char in GV name you have spotted).
- I don't have multiple monitors so unfortunately I can't check anything that way. Should the piece of code you posted be incorporated, or what do you meant with it?

- I will probably have to find some other way to enumerate the controls but what "GetControlID" function do you mean? It rather seems it's something related to ASP.NET or .NET Framework, not the 'basic' Win32 API.

MT4 logically knows the IDs and handles of controls since it's the app that created them. We don't. All we need to know are the HANDLES or IDs.

  • We can use GetDlgCtrlID() to get the ID of control but we must know the handle first,
  • We can use GetDlgItem() to get the handle of control but we must know the ID first,
  • We can use GetDlgItemText() to get the caption text but we must know the ID first,
  • So in every case, we have the "chicken or the egg" problem.

I haven't found any other way of getting into that. I don't know how could I use something like EnumerateChildWindows() from within mql4 since it deals with a pointer to application-defined callback function. The only way I'm thinking of at this moment is the ugly way:

  1. make a file (a tiny database; csv or something that, or just a string array within the mql4 code) with all possible caption alternatives for every locale,
  2. detect Windows UI locale (via WinAPI) and MT4 locale (from menu),
  3. read appropriate data from that file and try to find the caption text that really does exist in opened window,
  4. use it.

Another way (an idea of this moment ;-) could be collecting the handles from coordinates. They happen to stay the same, relative to lower right corner of the parent box. This would solve the button issues. But even in this case, we have to know the Input tab handle to determine if it's a MT4 input box at all !

Please note I'm an absolute newbie in coding; this is the third mql4 thing I coded, and my first touch ever with the Windows API. Perhaps there's a simple way of getting the handles but I just don't see it. I will be very glad for any hint on how to do it. Maybe I'm starting to see a possibility as I'm typing this post.. let me try ;-))


Thanks for your input! Cheers :-)

 

Hi!

- Yes - no way to use EnumerateChildWindows().
- Yes - GetControlID - i thought GetDlgCtrlID()
- i am waiting moderator approval, for another version of my Tester Control library. There is a code to find an expert window, ofc u dont know the exact name of the experts but u can identify the window by "sub windows/controls..." the parent handle is the mainwindow(terminal) parent. i dont know u use it or not just recommend: SpyWindows

int findWindowByCaption(int hWndParent, string caption) {
  int result = 0;
  string className; // the key is not initialized
  int child = FindWindowExA(hWndParent,0,"#32770",className);
  while (child != 0) {
    string name = "                                                  ";
    GetWindowTextA(child,name,50);
    if (caption == name || caption == "") {
      result = child;
      break;
    }
    child = FindWindowExA(hWndParent,child,"#32770",className);
  }
  return (result);
}
 
symr:

Hi!

i dont know u use it or not just recommend: SpyWindows

Hi, I'm using Window Detective (from SourceForge). I dived into it once more and found a way out! You have put me on the right track with the Control IDs, so we can say goodbye to all locale trouble! I have checked five MT4 builds from #218 (2008) to #402 (recent) and the IDs really don't change :-) New version already published, it was so simple:

#define CID_IDBOX         0x0000   // Child dialog box (parent to Load, Save and List)
#define CID_OK            0x0001   // OK button
#define CID_CANCEL        0x0002   // Cancel button
#define CID_RESET         0x3021   // Reset button
#define CID_TAB           0x3020   // Tab control
#define CID_LIST_ST       0x054D   // List control in tester
#define CID_LOAD_ST       0x0FAB   // Load button in tester
#define CID_SAVE_ST       0x0FAC   // Save button in tester
#define CID_LIST_EX       0x0567   // List control on chart
#define CID_LOAD_EX       0x0FAD   // Load button on chart
#define CID_SAVE_EX       0x0FAE   // Save button on chart

// We determine the active (topmost) window
int fWnd = GetForegroundWindow();
string cName = "123456789012345678901234567890";
GetClassNameA(GetParent(fWnd), cName, 30);
if (cName == "MetaQuotes::MetaTrader::4.00")
  {// Yes, it belongs to (some) MT4..
  cName = "1234567";
  GetClassNameA(fWnd, cName, 7);
  if (cName == "#32770")
    {// Yes, it is a dialog box, so let's try to get further handles..
    idbox = GetDlgItem(fWnd, CID_IDBOX);
    ok = GetDlgItem(fWnd, CID_OK);
    cancel = GetDlgItem(fWnd, CID_CANCEL);
    reset = GetDlgItem(fWnd, CID_RESET);
    tab = GetDlgItem(fWnd, CID_TAB);
    if (idbox && ok && cancel && reset && tab)
      {// Yes, all those elements are present so let's explore the idbox
      list = FindWindowExA(idbox, 0, "SysListView32", "list1");
      switch (GetDlgCtrlID(list))
        {// Only windows with one of two lists are valid: _ST (Strategy Tester) and _EX (Chart)
        case CID_LIST_ST: {load = GetDlgItem(idbox, CID_LOAD_ST); save = GetDlgItem(idbox, CID_SAVE_ST); break;}
        case CID_LIST_EX: {load = GetDlgItem(idbox, CID_LOAD_EX); save = GetDlgItem(idbox, CID_SAVE_EX); break;}
        default: {list = 0; load = 0; save = 0;}
        }
        if (list != 0) pWnd = fWnd; // a new window was found.
      }
    }                     
  }
      

CID_XXXX are constant across all builds I could test ;-)

Thanks for cooperation and kick into right direction!
More bug reports, please :-P ;-)))

 
I do not want to take away the glory from you, but is it possible u implement this code for MT5? :P
(MT4 is deprecated in the near of future :D)
 
symr:
I do not want to take away the glory from you, but is it possible u implement this code for MT5? :P
(MT4 is deprecated in the near of future :D)

A stand-alone native Windows tray utility will be a much better solution. I don't know MT5, maybe there's no need for it (?!). The best would be if MetaQuotes spent 10 minutes more time when releasing new MT4 build and make the windows resizable. Programming efforts? Near to none. Security/stability risk? NONE.
 

Edited & posted a fix three weeks ago:

2011.07.10: bugfix: indicator input boxes opened from within indicators list (Ctrl+I) couldn't be found.

NOT PUBLISHED until today (?), article was 'ready for publishing' all the time so I deleted it and submitted once more, let's see.

latest version always here: http://www.forexfactory.com/showthread.php?t=299017

 

Very great job. Thanks for your input!

Reason: