chenluhua1980
2026-01-19 30a7b29d0eb11ce87a9c0cafa0e5dd00c242d699
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#pragma once
#include <functional>
 
 
#ifndef EQSGRAPHWND_TAG
 
#ifdef _WIN32
 
#define EQSGRAPHWND_CLASSA        "EqsGraphWnd"
#define EQSGRAPHWND_CLASSW        L"EqsGraphWnd"
 
#ifdef UNICODE
#define EQSGRAPHWND_CLASS        EQSGRAPHWND_CLASSW
#else
#define EQSGRAPHWND_CLASS        EQSGRAPHWND_CLASSA
#endif
 
#else
#define EQSGRAPHWND_CLASS      "EqsGraphWnd"
#endif
 
 
#define EQSGRAPHWND_TAG            _T("EQSGRAPHWND_TAG")
 
#define EQSGRAPHWND_FIRST        (0U-2890U)
#define EQSGRAPHWND_LAST        (0U-2850U)
#define EQSGRAPHWND_            (EQSGRAPHWND_FIRST - 1)
 
 
#ifndef MIN
#define MIN(X,Y) (((X)>(Y))?(Y):(X))
#endif
 
#ifndef MAX
#define MAX(X,Y) (((X)>(Y))?(X):(Y))
#endif
 
#define EQITEM_INDICATOR_COUNT        8
 
 
enum EIndicatorState
{
    INDICATOR_STATE_HIDDEN = 0,
    INDICATOR_STATE_HIGHLIGHT = 1,
    INDICATOR_STATE_GRAY = 2,
};
 
typedef struct tagEQSGRAPHWND_NMHDR
{
    NMHDR        nmhdr;
    DWORD        dwData;
    DWORD        dwData1;
    DWORD        dwData2;
} EQSGRAPHWND_NMHDR;
 
typedef struct tagEQITEM
{
    unsigned int id;
    RECT rect;
    char text[64];
    BOOL bHighlight;
    int nShowType;
    DWORD_PTR pData;
    DWORD_PTR pInPins;
    DWORD_PTR pOutPins;
    int nFlashFlag;
    BYTE nIndicatorState[EQITEM_INDICATOR_COUNT]; // 0=隐藏, 1=高亮, 2=灰色
} EQITEM;
 
typedef struct tagPIN
{
    int nIndex;
    int nType;
    char text[64];
    BOOL bHighlight;
    EQITEM* pItem;
    tagPIN *pConnectedPin;
    POINT ptConnectedLine[6];
    int nLinePtCount;
    DWORD_PTR pData;
} PIN;
 
#define ITEM_NORMAL        0
#define ITEM_SMALL        1
#define ITEM_LARGE        2
 
#endif
 
typedef std::function<bool(PIN *pPin1, PIN *pPin2)> ONCONNECTPIN;
typedef std::function<bool(PIN *pPin)> ONDISCONNECTPIN;
typedef std::function<bool(EQITEM* pItem)> ONDELETEEQITEM;
typedef std::function<void(EQITEM* pItem, int x, int y)> ONEQITEMPOSCHANGED;
 
typedef struct _EqsGraphListener
{
    ONCONNECTPIN            onConnectPin;
    ONCONNECTPIN            onCheckConnectPin;
    ONDISCONNECTPIN            onDisconnectPin;
    ONDELETEEQITEM            onDeleteEqItem;
    ONEQITEMPOSCHANGED        onEqItemPosChanged;
    ONDELETEEQITEM            onDblckEqItem;
    ONDELETEEQITEM            onRclickEqItem;
    ONDELETEEQITEM            onSelectEqItem;
} EqsGraphListener;
 
class CEqsGraphWnd
{
    typedef struct tagRECTF
    {
        float    left;
        float    top;
        float    right;
        float    bottom;
    } RECTF;
 
public:
    CEqsGraphWnd();
    ~CEqsGraphWnd();
 
public:
    static BOOL RegisterWndClass();
    static CEqsGraphWnd* FromHandle(HWND hWnd);
    void SetFrameColor(COLORREF color);
    void SetBkgndColor(COLORREF color);
 
public:
    void EnableScroll(BOOL bEnable);
    void EnableMultiSelect();
    void SetItemRound(int nRound);
    void SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel);
    void SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel);
    void SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel);
    void SetOnListener(EqsGraphListener& listener);
    BOOL SetCurSel(int nSel);
    BOOL SetCurSel(CString strItemName);
    BOOL SetCurSel(DWORD_PTR pData);
    EQITEM * AddItem(int id, CString strText, DWORD_PTR dwData, int nType = ITEM_NORMAL);
    void RemoveItem(EQITEM* pItem);
    PIN * AddPin(EQITEM* pItem, int nType, CString strName, DWORD_PTR dwData);
    int DeleteItem(EQITEM* pItem);
    void DeleteAllItems();
    void SetItemSelectState(int nIndex, BOOL bSelect);
    void SetCurrentItem(EQITEM* pItem);
    BOOL GetItemRect(EQITEM* pItem, LPRECT lpRect);
    BOOL GetItemWarperRect(EQITEM* pItem, LPRECT lpRect);
    BOOL GetInPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect);
    BOOL GetOutPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect);
    BOOL GetPinPoint(PIN *pPin, LPPOINT lpPoint);
    EQITEM* GetItem(DWORD_PTR dwData);
    PIN * GetPin(DWORD_PTR dwItemData, DWORD_PTR dwPinData);
    int ConnectPin(DWORD_PTR dwItem1Data, DWORD_PTR dwPin1Data, DWORD_PTR dwItem2Data, DWORD_PTR dwPin2Data);
    void SetItemText(EQITEM* pItem, CString strText);
    void SetItemType(EQITEM* pItem, int type);
    void SetItemPos(EQITEM* pItem, int x, int y);
    void FlashItem(EQITEM* pItem);
    void AnimationItem(EQITEM*pItem);
    void ShowItemIndicator(DWORD_PTR dwItemData, int state, int nIndex = 0);
    void SetIndicatorSize(int nSize);
    void SetIndicatorMargin(int nMargin);
 
private:
    void Init();
    void InitFont();
    void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
    void Release();
    void ReleaseItem(EQITEM* pItem);
    void ReleaseAllItems();
    void CalculateScollbar();
    void CalculateMapPos();
    void CalculateMagneticLine(EQITEM* pItem, LPRECT lprcItemRect, int &hoz, int &ver);
    int HighTest(POINT pt, OUT EQITEM*& pItem, OUT PIN *& pPin);
    int GetPinState(PIN *pPin);
    void ClearConnectedLinePoint(EQITEM*& pItem);
    void DrawMagneticLine(LPRECT lprcClient, int nHozLine1, int nHozLine2, int nVerLine1, int nVerLine2);
    void DrawArrow(Gdiplus::Graphics *pGraphics, Gdiplus::Brush* pBrush, Gdiplus::Pen *pPen,
        int x, int y, int nArrowLen);
    void DrawDropItemRectangle(LPRECT lpRect1, LPRECT lpRect2);
    void DrawPinConnectedLine(Gdiplus::Graphics *pGraphics, Gdiplus::Brush *pBrush, Gdiplus::Pen *pPen, LPPOINT lpPt1, LPPOINT lpPt2,
        LPRECT lpRect1, LPRECT lpRect2, PIN *pOwnerPin);
    void DrawPinWillConnectLine(COLORREF color, LPPOINT lpPt1, LPPOINT lpPt2);
    double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2);
    static CEqsGraphWnd* Hook(HWND hWnd);
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
    LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
    LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
    LRESULT OnNcPaint(WPARAM wParam, LPARAM lParam);
    LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
    LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
    LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
    LRESULT OnRButtonDown(WPARAM wParam, LPARAM lParam);
    LRESULT OnLButtonDblclk(WPARAM wParam, LPARAM lParam);
    LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam);
    LRESULT OnMouseHWheel(WPARAM wParam, LPARAM lParam);
    LRESULT OnKeyDown(WPARAM wParam, LPARAM lParam);
    LRESULT OnSize(WPARAM wParam, LPARAM lParam);
    LRESULT OnVScroll(WPARAM wParam, LPARAM lParam);
    LRESULT OnHScroll(WPARAM wParam, LPARAM lParam);
    LRESULT OnNitify(WPARAM wParam, LPARAM lParam);
 
private:
    EQITEM*        m_pCurItem;
    int            m_nFlashCount;
    EQITEM*        m_pFlashItem;
    EQITEM*        m_pAnimationItem;
    PIN *        m_pCurPin;
    PIN *        m_pSelLineOutPin;        // 选中的连线的两个pin中的out pin
 
private:
    HWND        m_hWnd;
    COLORREF    m_crBkgnd;
    COLORREF    m_crFrame;
    HFONT        m_hFontTitle;
 
private:
    BOOL m_bUseGdiPlus;                    // 使用GDI+绘图?
    COLORREF m_crItemBackground[2];        // item的颜色,normal, active
    COLORREF m_crItemFrame[2];            // item的边框,normal, active
    COLORREF m_crItemNameText[2];
    COLORREF m_crItemIdText[2];
    COLORREF m_crPinBkgnd[3];            // pin的颜色,normal, active, enable connect
    int m_nCurSel;
    EqsGraphListener m_listener;
    CPtrArray m_arItem;
    BOOL m_bMultiSelect;
    int m_nItemRound;
 
private:
    int m_nStageCx;            // 画布大小
    int m_nStageCy;
    int m_nOffsetX;
    int m_nOffsetY;
    int m_nIndicatorSize;
    int m_nIndicatorMargin;
 
    // 动画
    RECTF m_rcAnimation;
    RECTF m_rcAninationStep;
    int m_nAninationStep;
    int m_nAninationDuration;        // ms
 
    // 字体
    HFONT m_hFontName;
    HFONT m_hFontId;
 
private:
    HWND m_hWndMapPos;
    BOOL m_bEnableScroll;
    int m_nMagneticLinHoz;
    int m_nMagneticLinVer;
};