Das würde gehen wenn nicht ein Bug in Wnd.mqh wäre.
CNutton ist von CWndObj und dieses von CWnd abgeleitet.
In CWnd ist OnMouseUp() für den Doppelclick verantwortlich. (Zeile 610)
//+------------------------------------------------------------------+ //| Handler of releasing the left mouse button | //+------------------------------------------------------------------+ bool CWnd::OnMouseUp(void) { if(IS_CAN_DBL_CLICK) { uint last_time=GetTickCount(); Print(last_time-m_last_click); // hab ich eingefügt, irgendwas stimmt hier nicht if(m_last_click==0 || last_time-m_last_click>CONTROLS_DBL_CLICK_TIME) { m_last_click=(last_time==0) ? 1 : last_time; } else { m_last_click=0; return(OnDblClick()); } } if(IS_CAN_DRAG) return(OnDragEnd()); if(!IS_CLICKS_BY_PRESS) return(OnClick()); //--- handled return(true); }
Dort siehst du daß das Macro IS_CAN_DBL_CLICK ausgeführt wird, daß (m_prop_flags&WND_PROP_FLAG_CAN_DBL_CLICK)!=0 abfragt.
Daraus folgt: Beim Erstellen des Buttons muss folgende Zeile eingefügt werden:
m_button1.PropFlagsSet(WND_PROP_FLAG_CAN_DBL_CLICK);
Setz dir einen Haltebunkt auf Zeile 612 und beobachte das Verhalten.
Ich hab das mit MQL5\Experts\Examples\Controls\Controls.mq5 bzw MQL5\Experts\Examples\Controls\ControlsDialog.mqh getestet.
//+------------------------------------------------------------------+ //| Create the "Button1" button | //+------------------------------------------------------------------+ bool CControlsDialog::CreateButton1(void) { //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button1.Create(m_chart_id,m_name+"Button1",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button1.Text("Button1")) return(false); m_button1.PropFlagsSet(WND_PROP_FLAG_CAN_DBL_CLICK); if(!Add(m_button1)) return(false); //--- succeed return(true); }
EVENT_MAP gehört natürlich auch adaptiert.
EVENT_MAP_BEGIN(CControlsDialog) ... ON_EVENT(ON_DBL_CLICK,m_button1,OnDblClickButton1) ... EVENT_MAP_END(CAppDialog)
Es fehlt halt hier in MQL an so vielem!
Das würde gehen wenn nicht ein Bug in Wnd.mqh wäre.
CNutton ist von CWndObj und dieses von CWnd abgeleitet.
In CWnd ist OnMouseUp() für den Doppelclick verantwortlich. (Zeile 610)
Dort siehst du daß das Macro IS_CAN_DBL_CLICK ausgeführt wird, daß (m_prop_flags&WND_PROP_FLAG_CAN_DBL_CLICK)!=0 abfragt.
Daraus folgt: Beim Erstellen des Buttons muss folgende Zeile eingefügt werden:
Setz dir einen Haltebunkt auf Zeile 612 und beobachte das Verhalten.
Ich hab das mit MQL5\Experts\Examples\Controls\Controls.mq5 bzw MQL5\Experts\Examples\Controls\ControlsDialog.mqh getestet.
EVENT_MAP gehört natürlich auch adaptiert.
Es fehlt halt hier in MQL an so vielem!
Danke Otto, werd ich am abend probieren :-)
//+------------------------------------------------------------------+ //| ControlsDialog.mqh | //| Copyright 2009-2017, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Edit.mqh> #include <Controls\DatePicker.mqh> //#include <Controls\ListView.mqh> #include <Controls\ComboBox.mqh> //#include <Controls\SpinEdit.mqh> #include <Controls\RadioGroup.mqh> #include <Controls\CheckBox.mqh> #include <Trade\trade.mqh> #include <Controls\Wnd.mqh> CTrade trade; #include <Trade\PositionInfo.mqh> // wird verwendet für die Position Information Funktionen CPositionInfo __position; // initialisieren der Position Informationen z.B position.Profit(); #include <Trade\HistoryOrderInfo.mqh> // wird verwendet für die Order History Informationen CHistoryOrderInfo __historyorder; // initialisieren der Order History Informationen z.B _historyorder.Profit(); //+------------------------------------------------------------------+ //| defines | //+------------------------------------------------------------------+ //--- indents and gaps #define INDENT_LEFT (5) // indent from left (with allowance for border width) #define INDENT_TOP (5) // indent from top (with allowance for border width) #define INDENT_RIGHT (11) // indent from right (with allowance for border width) #define INDENT_BOTTOM (11) // indent from bottom (with allowance for border width) #define CONTROLS_GAP_X (5) // gap by X coordinate #define CONTROLS_GAP_Y (5) // gap by Y coordinate //--- for buttons #define BUTTON_WIDTH (67) // size by X coordinate #define BUTTON_HEIGHT (20) // size by Y coordinate //--- for the indication area #define EDIT_HEIGHT (20) // size by Y coordinate //--- for group controls #define GROUP_WIDTH (150) // size by X coordinate #define LIST_HEIGHT (179) // size by Y coordinate #define RADIO_HEIGHT (56) // size by Y coordinate #define CHECK_HEIGHT (93) // size by Y coordinate //+------------------------------------------------------------------+ //| Class CControlsDialog | //| Usage: main dialog of the Controls application | //+------------------------------------------------------------------+ class CTradePanel : public CAppDialog { private: CButton m_button1; // Buy CButton m_button2; // Sell CButton m_button3; // Close CButton m_button4; // Line CButton m_button5; // Objects CButton m_button6; // BE CRadioGroup m_radio_group1; // Risiko CRadioGroup m_radio_group2; // Gültig bis CEdit m_edit1; // Risiko eingeben CEdit m_edit2; // SL eingeben CEdit m_edit3; // TP eingeben CEdit m_edit4; // TSL eingeben CEdit m_edit5; // Price Line Distance CEdit m_edit6; // Fibo MA CEdit m_edit7; // Trend MA CDatePicker m_date; // Datum eingeben für gültig bis CCheckBox m_check_box1; // Trailing CCheckBox m_check_box2; // SL CCheckBox m_check_box3; // TP CCheckBox m_check_box4; // Price Lines CCheckBox m_check_box5; // H4 0 aktuelle Bar H4 CCheckBox m_check_box6; // H4 1, 1 Bar Zurück H4 CCheckBox m_check_box7; // D1 0 aktuelle Bar H4 CCheckBox m_check_box8; // D1 1, 1 Bar Zurück H4 CCheckBox m_check_box9; // AutoTrading On/Off CCheckBox m_check_box10; // Fibo Level 23.6 CCheckBox m_check_box11; // Fibo Level 38.2 CCheckBox m_check_box12; // Fibo Level 50 CCheckBox m_check_box13; // Fibo Level 61.8 CCheckBox m_check_box14; // Fibo Level 1 CComboBox m_combo_box1; // Fibo_MA_Price public: CTradePanel(void){}; ~CTradePanel(void){}; //--- create virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2); //--- chart event handler virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); virtual void OnTick(void); virtual void OnTimer(void); virtual int OnInit(); protected: //--- create dependent controls //bool CreateEdit(void); bool CreateButton6(void); // BE Button //--- handlers of the dependent controls events void OnClickButton6(void); // BE Button void OnDblClickButton6(void); // BE Button }; //+------------------------------------------------------------------+ //| Event Handling | //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CTradePanel) ON_EVENT(ON_CLICK,m_button6,OnClickButton6) ON_EVENT(ON_DBL_CLICK,m_button6,OnDblClickButton6) EVENT_MAP_END(CAppDialog) //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Create | //+------------------------------------------------------------------+ bool CTradePanel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) { if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false); //--- create dependent controls if(!CreateButton6()) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button" button | //+------------------------------------------------------------------+ bool CTradePanel::CreateButton6(void) { //--- coordinates int x1=INDENT_LEFT+2*(BUTTON_WIDTH+CONTROLS_GAP_X); int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button6.Create(m_chart_id,m_name+"Button6",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button6.Text("BE")) return(false); m_button6.PropFlagsSet(WND_PROP_FLAG_CAN_DBL_CLICK); if(!Add(m_button6)) return(false); //--- succeed return(true); } void CTradePanel::OnTick(void) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CTradePanel::OnInit() { trade.SetExpertMagicNumber(MN); //--- Trade Requests werden im asynchronen Modus mithilfe der Funktion OrderSendAsync() gesendet //--- für eine 2te Magic Number muss die Klasse CTrade ein 2tes mal mit anderer bezeichnung verwendet werden trade.SetAsyncMode(true); //--- Asynchronen Trade Modus verwenden if(!TradePanel.Create(ChartID(),"Trade Panel",0,20,20,305,290)) return(INIT_FAILED); TradePanel.Run(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CTradePanel::OnTimer(void) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
Hab eigentlich alles genauso gemacht wie Du schreibt Otto, aber funktioniert trotzdem nicht
hab sogar die
#include <Controls\Wnd.mqh>
eingefügt, hilft aber nix, ich bleib bei einem klick hängen
wobei, ich versteh ja nicht, wo die
IS_CAN_DBL_CLICKherkommt, die finde ich nichtmal über die Suchfunktion in der Doku
wenn ich das ganze Analysiere und mir einen Haltepunkt in Zeile 612 und 615 einbaue dann bekomme ich
also aus 615 wird 616 weil ich die Zeile mit der Print vom Otto noch eingefügt habe
mein großes Problem, er bricht mir ja schon beim ersten Click ab.
weil wenn ich den ersten Slick setze
wenn ich das weiterdrücke mit F5 kommt dann
so, jetzt hab ich weitergesucht,
das kommt aus den Defines
#define CONTROLS_DBL_CLICK_TIME (4000) // double click interval
original steht der Wert auf 100
wenn ich den erhöhe dann passiert was eigenartiges
erster Click ist der EinfachClick und jeder folgende muss in dieser definierten Zeit passieren das der DBL_Click ausgeführt wird.
dann brauche ich quasi 3 Clicks für den DBL_Click
wenn ich jetzt hergehe, und diese Einstellung auf 100 lasse, und dafür in der Funktion
bool CWnd::OnMouseUp(void) { if(IS_CAN_DBL_CLICK) { uint last_time=GetTickCount(); Print(last_time-m_last_click); if(m_last_click==0 || last_time-m_last_click>CONTROLS_DBL_CLICK_TIME) { Print("Klicks"); m_last_click=(last_time==0) ? 1 : last_time; } else { m_last_click=0; return(OnDblClick()); } } if(IS_CAN_DRAG) return(OnDragEnd()); if(!IS_CLICKS_BY_PRESS) return(OnClick()); //--- handled return(true); }
bei der Abrage der Zeit das < auf ein > ändere
das sieht dann so aus
bool CWnd::OnMouseUp(void) { if(IS_CAN_DBL_CLICK) { uint last_time=GetTickCount(); Print(last_time-m_last_click); if(m_last_click==0 || last_time-m_last_click<CONTROLS_DBL_CLICK_TIME) { Print("Klicks"); m_last_click=(last_time==0) ? 1 : last_time; } else { m_last_click=0; return(OnDblClick()); } } if(IS_CAN_DRAG) return(OnDragEnd()); if(!IS_CLICKS_BY_PRESS) return(OnClick()); //--- handled return(true); }
dann funktioniert die Funktion ganz normal
bin ich nicht normal oder ist Metaquotes das nicht?
Amando ich würde erstmal schauen ob das Ereigniss ON_DOUBLE_CLICK irgendwo definiert .
Ich konnte nichts finden aber die IDE kennt ihn ja.
Meiner Meinung nach kommt er nicht von Windows. So das er emuliert werden muss . Siehe Otto
Hier kannst du testen ober er überhaupt "ankommt" .
Ich konnte ihn nicht erkennen, vielleicht du ja
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id==CHARTEVENT_CUSTOM+ON_DOUBLE_CLICK) { } // Breakpoint hier und Werte prüfen gegenprüfen oder einfach mit Print ausgeben. }
Komisch das der jetzt nicht rot dargestellt wird.
Ich tippe das er nicht übergeben wird. MQ schweigt sich ja immer bei Problemen aus.
Lässt lieber die User erst im Forum fragen stellen und beantwortet die dann mit Glück . Ich hasse dieses Verhalten an MQ .
Dort würde dann stehen was bei einem Doppel Klick passieren soll.
Das ist der Ereignissrotine für die Grafik. Die ID ist nur ein INT Wert passend zum Ergeigniss
Ich habe das mit der EasyAndFastGUI Artikeln damals "gewurschtelt" :-) Build 16 .
Das er jetzt dein ON_DOUBLE_CLICK nicht erkennt heist das er in der EasyAndFastGUI definiert ist.
Aber kurz über lang ....du wirst nicht glücklich.
Mache lieber 2 Buttons und ärger dich nicht über den BETA-STATUS der Grafik-Schnittstelle.
Hab die Definition nun doch gefunden .
Hier die Biliothek -> https://www.mql5.com/de/code/19703
//+------------------------------------------------------------------+ //| Defines.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ //--- Режим "Эксперт в окне" #define EXPERT_IN_SUBWINDOW false //--- Имя класса #define CLASS_NAME ::StringSubstr(__FUNCTION__,0,::StringFind(__FUNCTION__,"::")) //--- Имя программы #define PROGRAM_NAME ::MQLInfoString(MQL_PROGRAM_NAME) //--- Тип программы #define PROGRAM_TYPE (ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE) //--- Предотвращение выхода из диапазона #define PREVENTING_OUT_OF_RANGE __FUNCTION__," > Предотвращение выхода за пределы массива." //--- Шаг таймера (миллисекунды) #define TIMER_STEP_MSC (16) //--- Задержка перед включением перемотки счётчика (миллисекунды) #define SPIN_DELAY_MSC (-450) //--- Символ пробела #define SPACE (" ") //--- Для представления любых названий в строковом формате #define TO_STRING(A) #A //--- Распечатка данных события #define PRINT_EVENT(SID,ID,L,D,S) \ ::Print(__FUNCTION__," > id: ",TO_STRING(SID)," (",ID,"); lparam: ",L,"; dparam: ",D,"; sparam: ",S); //--- Идентификаторы событий #define ON_WINDOW_EXPAND (1) // Разворачивание формы #define ON_WINDOW_COLLAPSE (2) // Сворачивание формы #define ON_WINDOW_CHANGE_XSIZE (3) // Изменение размеров окна по оси X #define ON_WINDOW_CHANGE_YSIZE (4) // Изменение размеров окна по оси Y #define ON_WINDOW_TOOLTIPS (5) // Нажатие на кнопке "Всплывающие подсказки" //--- #define ON_CLICK_LABEL (6) // Нажатие на текстовой метке #define ON_CLICK_BUTTON (7) // Нажатие на кнопке #define ON_CLICK_MENU_ITEM (8) // Нажатие на пункте меню #define ON_CLICK_CONTEXTMENU_ITEM (9) // Нажатие на пункте меню в контекстном меню #define ON_CLICK_FREEMENU_ITEM (10) // Нажатие на пункте свободного контекстного меню #define ON_CLICK_CHECKBOX (11) // Нажатие на чекбоксе #define ON_CLICK_GROUP_BUTTON (12) // Нажатие на кнопке в группе #define ON_CLICK_ELEMENT (13) // Нажатие на элементе #define ON_CLICK_TAB (14) // Переключение вкладки #define ON_CLICK_SUB_CHART (15) // Нажатие на объекте-графике #define ON_CLICK_INC (16) // Изменение счётчика вверх #define ON_CLICK_DEC (17) // Изменение счётчика вниз #define ON_CLICK_COMBOBOX_BUTTON (18) // Нажатие на кнопке комбо-бокса #define ON_CLICK_LIST_ITEM (19) // Выбор пункта в списке #define ON_CLICK_COMBOBOX_ITEM (20) // Выбор пункта в списке комбобокса #define ON_CLICK_TEXT_BOX (21) // Активация текстового поля ввода //--- #define ON_DOUBLE_CLICK (22) // Двойной клик левой кнопки мыши #define ON_END_EDIT (23) // Окончание редактирования значения в поле ввода //--- #define ON_OPEN_DIALOG_BOX (24) // Событие открытия диалогового окна #define ON_CLOSE_DIALOG_BOX (25) // Событие закрытия диалогового окна #define ON_HIDE_CONTEXTMENUS (26) // Скрыть все контекстные меню #define ON_HIDE_BACK_CONTEXTMENUS (27) // Скрыть контекстные меню от текущего пункта меню //--- #define ON_CHANGE_GUI (28) // Графический интерфейс изменился #define ON_CHANGE_DATE (29) // Изменение даты в календаре #define ON_CHANGE_COLOR (30) // Изменение цвета посредством цветовой палитры #define ON_CHANGE_TREE_PATH (31) // Путь в древовидном списке изменён #define ON_CHANGE_MOUSE_LEFT_BUTTON (32) // Изменение состояния левой кнопки мыши //--- #define ON_SORT_DATA (33) // Сортировка данных #define ON_MOUSE_BLUR (34) // Курсор мыши вышел из области элемента #define ON_MOUSE_FOCUS (35) // Курсор мыши зашёл в область элемента #define ON_REDRAW_ELEMENT (36) // Перерисовка элемента #define ON_MOVE_TEXT_CURSOR (37) // Перемещение текстового курсора #define ON_SUBWINDOW_CHANGE_HEIGHT (38) // Изменение высоты подокна //--- #define ON_SET_AVAILABLE (39) // Установить доступные элементы #define ON_SET_LOCKED (40) // Установить заблокированные элементы //--- #define ON_WINDOW_DRAG_END (41) // Перетаскивание формы завершено //+------------------------------------------------------------------+
Also ist der Wert 22 für Doppelklick.
Jetzt noch den Wert von CHARTEVENT_CUSTOM dazuaddieren dann hast du den Wert der bei ID stehen muss.
Kommste mit ? :-)
- www.mql5.com
Hab die Definition nun doch gefunden .
Hier die Biliothek -> https://www.mql5.com/de/code/19703
Also ist der Wert 22 für Doppelklick.
Jetzt noch den Wert von CHARTEVENT_CUSTOM dazuaddieren dann hast du den Wert der bei ID stehen muss.
Kommste mit ? :-)
das wäre mir ja noch klar Christian,
if(id==CHARTEVENT_CUSTOM+22)
nur was nützt mir das?
mir ist auch noch klar, das ich in der OnChartEvent die Ereignisse definiere wo eine Eingabe am Chart erfolgt.
Interessanterweise, ich muss das ja für den Click auch nicht definieren
https://www.mql5.com/de/docs/event_handlers/onchartevent
ausserdem, wie würde ich den Button ansprechen? das wäre ja das nächste Thema dabei ;-)
was ich in der On Chart mache, ist die Beschreibung der Linien ändern
if(id==CHARTEVENT_OBJECT_DRAG) ObjectSetString(0,"TPLine",OBJPROP_TEXT,0,"TP "+" "+ DoubleToString(MathAbs(ObjectGetDouble(0,"TPLine",OBJPROP_PRICE,0)-ObjectGetDouble(0,"BuySellLine",OBJPROP_PRICE,0)) *MathPow(10,_Digits),0)+" EUR "+ DoubleToString((MathAbs(ObjectGetDouble(0,"TPLine",OBJPROP_PRICE,0)-ObjectGetDouble(0,"BuySellLine",OBJPROP_PRICE,0)) *MathPow(10,_Digits)*SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE))*Lots,2) );
das funktioniert problemlos, aber da schreibe ich ja auch nur den Text der Linien neu
btw, mit den 2 Button hast Du natürlich recht, das ist allerdings ein Platzproblem und eigentlich störts ja nicht wirklich wenn das gehen würde
ich verwende einmal klicken für die BreakEven Line reinsetzten
Doppelklick für gleich auf BE setzen.
Wenn die Linie zuerst kommt wärs mir auch nicht so tragisch, weil ich ja mit den Button Objekte eh alle lösche
- www.mql5.com
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Hallo,
ich hab mir ja ein Panel erstellt, einfach nur um damit auf dem Tablet traden zu können
Jetzt hab ich den Button6 für Breakeven.
den würde ich gerne doppelt belegen
einmal mit dem Ereignis OnClick
einmal mit dem Ereignis OnDblClick
das funktioniert leider nicht.
den DBL_Click ignoriert der MT5
definiert hab ich das ganze so
rest vom Code hab ich rausgelöscht wegen der übersichtlichkeit
jetzt ist es so, das der Click immer funktioniert, der DBL_Click leider nie.
geht das nicht zusammen auf einem Button?
danke
amando