Undock MT5 (and maybe MT4) charts from terminal

To add comments, please log in or register
kypa
976
kypa  

Hello!

This is the beginning of the code:

//+----------------------------------------------------------------------------------------------------+
//|                                                                                         undock.mq5 |
//+----------------------------------------------------------------------------------------------------+

#import "user32.dll"
   int GetParent(long hWnd);
   int SetParent(long hWndChild, long hWndNewParent);
   bool SetWindowPos(long hWnd, long hWndInsertAfter, int x, int y, int width, int height, uint uFlags);
   long CreateWindowEx(uint dwExStyle,uint lpClassName,uint lpWindowName,uint dwStyle,int x,int y,int nWidth,int nHeight,int hWndParent,int hMenu,int hInstance,uint lpParam);
   void keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo);
#import

void OnStart()
  {
   if(ChartGetInteger(0,CHART_IS_MAXIMIZED,0)==1)
     {
      keybd_event(0x12,0,0,0);
      keybd_event(0x52,0,0,0);
      keybd_event(0x12,0,0x0002,0);
      keybd_event(0x52,0,0x0002,0);
     }

   long ThisChartID = ChartID();
   long NewWindowHandle, ThisChartHandle, ThisChartParentHandle, ThisChartGrandParentHandle, ThisChartGrandGrandParentHandle;

   ChartGetInteger(ThisChartID,CHART_WINDOW_HANDLE,0,ThisChartHandle);

   ThisChartParentHandle=GetParent(ThisChartHandle);
   ThisChartGrandParentHandle=GetParent(ThisChartParentHandle);
   ThisChartGrandGrandParentHandle=GetParent(ThisChartGrandParentHandle);
   NewWindowHandle=CreateWindowEx(0,NULL,NULL,0,100,200,500,500,NULL,NULL,NULL,NULL); 
   
   //SetParent(ThisChartHandle,NewWindowHandle);
   Comment(NewWindowHandle);
  }

//+----------------------------------------------------------------------------------------------------+

Terminal says "cannot find 'CreateWindowsEx' in 'user32.dll'". It's most probably me not declaring it properly, but should it return some other kind of error if that is the problem?

kypa
976
kypa  
SetParent(ThisChartHandle,NULL);
SetParent(ThisChartParentHandle,NULL);

These two functions undock the chart, however the first does it without buttons and frames and the second crashes the terminal.

That should mean an empty window must be created and the chart (without buttons and frame) parented into it.

kypa
976
kypa  

Not sure exactly what I'm doing, but CreateWindowEx returned a zero and ThisChartHandle window can get a titlebar.

//+----------------------------------------------------------------------------------------------------+
//|                                                                                         undock.mq5 |
//+----------------------------------------------------------------------------------------------------+

#import "user32.dll"
   int GetParent(long hWnd);
   int SetParent(long hWndChild, long hWndNewParent);
   bool SetWindowPos(long hWnd, long hWndInsertAfter, int x, int y, int width, int height, uint uFlags);
   long CreateWindowExA(uint dwExStyle,const char &lpClassName,const char &lpWindowName,uint dwStyle,int x,int y,int nWidth,int nHeight,int hWndParent,int hMenu,int hInstance,long lpParam);
   void keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo);
   long SetWindowLongPtrA(long hWnd,int nIndex,long dwNewLong);
#import

void OnStart()
  {
   if(ChartGetInteger(0,CHART_IS_MAXIMIZED,0)==1)
     {
      keybd_event(0x12,0,0,0);
      keybd_event(0x52,0,0,0);
      keybd_event(0x12,0,0x0002,0);
      keybd_event(0x52,0,0x0002,0);
     }
   const char null=NULL;
   long ThisChartID = ChartID();
   long NewWindowHandle, ThisChartHandle, ThisChartParentHandle, ThisChartGrandParentHandle, ThisChartGrandGrandParentHandle;

   ChartGetInteger(ThisChartID,CHART_WINDOW_HANDLE,0,ThisChartHandle);

   ThisChartParentHandle=GetParent(ThisChartHandle);
   ThisChartGrandParentHandle=GetParent(ThisChartParentHandle);
   ThisChartGrandGrandParentHandle=GetParent(ThisChartGrandParentHandle);
   NewWindowHandle=CreateWindowExA(0x00040000|0x00C00000,null,null,0,200,300,500,500,NULL,NULL,NULL,NULL); 
   //SetParent(ThisChartHandle,NULL);
   //SetWindowLongPtrA(ThisChartHandle,-16,0x00040000|0x00C00000);
   //SetWindowPos(ThisChartHandle,0,200,300,500,500,0x0020);
   SetWindowPos(NewWindowHandle,0,200,300,500,500,0x0020);
   Comment(NewWindowHandle);
  }

//+----------------------------------------------------------------------------------------------------+
kypa
976
kypa  

This undocks the chart in almost usable form:

//+----------------------------------------------------------------------------------------------------+
//|                                                                                         undock.mq5 |
//+----------------------------------------------------------------------------------------------------+

#import "user32.dll"
   int SetParent(long hWndChild, long hWndNewParent);
   bool SetWindowPos(long hWnd, long hWndInsertAfter, int x, int y, int width, int height, uint uFlags);
   void keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo);
   long SetWindowLongPtrA(long hWnd,int nIndex,long dwNewLong);
#import

void OnStart()
  {
   if(ChartGetInteger(0,CHART_IS_MAXIMIZED,0)==1)
     {
      keybd_event(0x12,0,0,0);
      keybd_event(0x52,0,0,0);
      keybd_event(0x12,0,0x0002,0);
      keybd_event(0x52,0,0x0002,0);
     }

   long ThisChartID = ChartID();
   long ThisChartHandle;
   ChartGetInteger(ThisChartID,CHART_WINDOW_HANDLE,0,ThisChartHandle);

   SetParent(ThisChartHandle,NULL);
   SetWindowLongPtrA(ThisChartHandle,-16,0x00040000|0x10000000|0x00000000|0x00C00000|0x00080000|0x00010000|0x00020000);
   SetWindowPos(ThisChartHandle,0,200,300,500,500,0x0020);
  }

//+----------------------------------------------------------------------------------------------------+

Limitations are if undocked chart is closed before the leftover docked window the terminal will crash. And leftover docked window can't be closed with mouse, ctrl+f4 should be used. Actually the whole main terminal window and everything on it becomes unclickable, it can be accessed only if undocked chart is minimized or the parts we want are undocked as well (through dragging).

kypa
976
kypa  

This works a little better:

//+----------------------------------------------------------------------------------------------------+
//|                                                                                         undock.mq5 |
//+----------------------------------------------------------------------------------------------------+

#import "user32.dll"
   int SetParent(long hWndChild, long hWndNewParent);
   int GetParent(long hWnd);
   bool SetWindowPos(long hWnd, long hWndInsertAfter, int x, int y, int width, int height, uint uFlags);
   void keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo);
   long SetWindowLongPtrA(long hWnd,int nIndex,long dwNewLong);
   bool ShowWindow(long hWnd,int nCmdShow);
#import

void OnStart()
  {
   if(ChartGetInteger(0,CHART_IS_MAXIMIZED,0)==1)
     {
      keybd_event(0x12,0,0,0);
      keybd_event(0x52,0,0,0);
      keybd_event(0x12,0,0x0002,0);
      keybd_event(0x52,0,0x0002,0);
     }

   long ThisChartID = ChartID();
   long ThisChartHandle, ThisChartParentHandle;
   ChartGetInteger(ThisChartID,CHART_WINDOW_HANDLE,0,ThisChartHandle);
   ThisChartParentHandle=GetParent(ThisChartHandle);
   SetParent(ThisChartHandle,NULL);
   SetWindowLongPtrA(ThisChartHandle,-16,0x00040000|0x10000000|0x00000000|0x00C00000|0x00080000|0x00010000|0x00020000);
   SetWindowPos(ThisChartHandle,-1,256,256,512,512,0);
   ShowWindow(ThisChartParentHandle,6);
  }

//+----------------------------------------------------------------------------------------------------+

Minimized empty window still must be closed before the undocked chart or terminal will crash.

The best solution would be undocked chart sibling to undocked Toolbox, Symbols, Navigator, etc. but I don't know how to do it.

There is documentation in MS site about user32, functions and meanings of values, for example:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx

SetWindowLong function (Windows)
  • msdn.microsoft.com
Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory. Note This function has been superseded by the SetWindowLongPtr function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function. Syntax...
To add comments, please log in or register