"

InputResizer: edit indicator and EA settings comfortably

by Dr.Hamdi Boukamcha
Name:
InputResizer: edit indicator and EA settings comfortably
Author: MaryJane (2011.06.23 13:32)
Rating: 10
Downloaded: 4608
Download:
InputResizer: edit indicator and EA settings comfortably   InputResizer.mq4 (11.2 Kb) View
InputResizer: edit indicator and EA settings comfortably   InputResizerEA.mq4 (11.9 Kb) View

Today’s expert advisors and custom indicators are overloaded with settings. Blessing 3 EA has 118 lines of input, The Beast EA has 155 and with every new version, the count of input parameters increases. Some more advanced pivot indicators have dozens of them. MT4 was designed years ago and offers a non-resizable dialog box showing only 8 lines of input. Majority of traders won’t mind it as they set their settings once for ever and forget. But if you are one of them who test, optimize, evaluate or just play around with different settings on daily basis, you could find my utility useful.

InputResizer is a set-and-forget utility. Once you set it up, you’re done with it. Attach it to one single chart and all the input windows, in all MT4 instances on your PC/VPS, become resizable.

InputResizer: edit indicator and EA settings comfortably

Attached are two variants – indicator and EA, both doing the same thing. Choose a variant and use it; don’t use both indicator and EA at once.

Indicator variant – InputResizer.mq4:
The indicator depends on incoming ticks, so if you choose it for whatever reason, you will have to wait for a tick until the indicator spots the window you have opened and manages it, so it’s good to attach it to a chart (pair) that receives ticks frequently – EURJPY and GBPJPY are good choices.

 

EA variant – InputResizerEA.mq4:
The advantage of using the EA is clear; it runs in loop mode and doesn’t depend on ticks. It checks for windows every 300 msec (default setting) so you will never have to wait. However, if you start your MT4 when the market is closed, you have to switch the WeekendMode (see below) on, or use a tick generator utility or script. There’s one little disadvantage in using the EA. I recommend using this variant, but it occupies a chart you can’t use for another EA. It’s a good idea to attach it to a dedicated chart (M1-W1, pair doesn’t matter), minimize this chart and not use it for other purposes.

Setup:

InputResizer: edit indicator and EA settings comfortably

Per default (set as above), InputResizer will place and resize every input window on its first appearance to specified coordinates (in pixels, relative to upper left screen corner). Then, if the input window (distinguished by EA/indicator name) re-appears (on any chart/platform), position/size at last window close will be applied.

If RememberSize=false, all windows will be opened with InitCustom (if true) coordinates, maximized if InitMaximized=true (InitMaximized overrides InitCustom), or at default position and size if both InitCustom and InitMaximized are false.

If RememberSize=true, the above is applied only for the first time a window appears. Then, coordinates are stored at each window close and re-applied next time. Stored coordinates override InitCustom and InitMaximized.

If Individual=true, coordinates will be stored for each EA/indicator name separately. This setting is only relevant if RememberSize=true.

SleepTime: (EA only) time between scans in milliseconds. Lower number results in faster response but increases CPU load.

WeekendMode: (EA only) if set to true, no need to use a tick simulator to get it running. Use for weekend testing! Set it back to false during normal trading hours to prevent unexpected behavior. Reason: Start() is called from within Init() in WeekendMode; this way to get an EA running is quick, dirty and incorrect.

Final notes:

  • DLLs must be allowed for InputResizer to work. Otherwise, you will receive an alert message.
  • If you open an input window of an indicator/EA for the first time, it will not resize until you select the input tab.
  • If you use the EA version and want to change its settings while running (F7), switch to Monthly timeframe, change what you need and switch back to any lower TF.
  • Coordinates are stored into global variables; they are persistent until you delete them. You can do this anytime by pressing F3 and deleting all global variables starting with ‘iRes’.

UPDATES:
2011.06.25:
bugfix: “z” character typo (thans to symr for spotting this bug).
2011.06.29:
upgrade: no need to input localised controls, more reliable operation, ability to handle multiple open input windows on different MT4 instances.
2011.07.10: bugfix: indicator input boxes opened from within indicators list (Ctrl+I) couldn’t be found.

16 comments: 1 2   To post a new comment, please log in or register

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

01.08.2011 08:45 MaryJane

symr:
I do not want to take away the glory from you, but is it possible u implement this code for MT5? 😛
(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.

01.07.2011 10:49 MaryJane

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

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 😛 ;-)))

29.06.2011 19:26 MaryJane

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);
}
29.06.2011 11:21 symr

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 🙂

29.06.2011 10:04 MaryJane

Hi!

Sorry for that but find some bugs-bunny… 😛

– 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…

#import "user32.dll"
  int GetSystemMetrics(int nIndex);
#import

#define SM_CMONITORS      0x80
#define HWND_TOPMOST      -1
#define HWND_NOTOPMOST    -2

if (GetSystemMetrics(SM_CMONITORS) > 1) {
  log("Multiple monitor systems");
  SetWindowPos(pWnd, HWND_TOPMOST, ....);
} else { 
  log("Single monitor systems");
  SetWindowPos(pWnd, HWND_NOTOPMOST, ....);
}

– 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.

InputResizer: edit indicator and EA settings comfortably

 

28.06.2011 19:42 symr

always wished for something like this, thanks a lot.
27.06.2011 20:53 golomolo

For Russian localization:

Chart_Tab=Входные параметры

Tester_Tab=Входные параметры

OK_Button=ОК

Cancel_Button=Отмена

Reset_Button=Сброс

Load_Button=Загрузить

Save_Button=Сохранить

Very useful unit, thank’s!

27.06.2011 07:19 yuritch

great job, this is really helpful stuff

Share this article

Leave a comment