123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- // SMachine.cpp: 实现文件
- //
- //#include <afx.h>
- #include "resource.h" // 主符号
- #include "stdafx.h"
- #include "SMachineDlg.h"
- //控件ID
- #define Dlg_Button_ManualTriggered 1 //手动触发事件按钮
- #define Dlg_Button_JumpToNext 2 //跳转至下一状态确认按钮
- #define Dlg_Edit_ManualEventName 101 //手动触发事件名称
- #define Dlg_Edit_NextStateName 102 //自动动触发事件名称
- #define Dlg_Edit_WaitEventList 103 //当前等待事件列表
- #define Dlg_Edit_RunHistory 104 //执行历史记录
- #define Dlg_Radio_GroupJump 301 //跳转方式
- #define Dlg_Radio_ManualJump 302 //手动跳转
- #define Dlg_Radio_AutoJump 303 //自动跳转
- #define Dlg_Check_1 201
- #define Dlg_Check_2 202
- SMachineDlg::CallMap SMachineDlg::g_HandleDlgMap; //消息处理窗口句柄集
- static int glo_BaseUnitX = LOWORD(GetDialogBaseUnits());
- static int glo_BaseUnitY = HIWORD(GetDialogBaseUnits());
- SMachineDlg::SMachineDlg(string title, string windowClass, SMDlgCallback object)
- {
- m_strTitle = title;
- m_strWindowClass = windowClass;
- m_DlgCallback = object;
- }
- SMachineDlg::~SMachineDlg()
- {
- if(m_hWnd)
- StopThread();
- }
- HWND SMachineDlg::GetWindowHandle()
- {
- return m_hWnd;
- }
- ATOM SMachineDlg::RegisterWindowClass(HINSTANCE hInstance)
- {
- WNDCLASSEX winDlg;
- memset(&winDlg, 0, sizeof(WNDCLASSEX));
- winDlg.lpszClassName = m_strWindowClass.c_str(); //设置类名称
- winDlg.cbSize = sizeof(WNDCLASSEX); //窗口类内存大小
- winDlg.cbClsExtra = 0; //为类额外分配内存,一般为0
- winDlg.cbWndExtra = 0; //为窗口额外分配内存,一般为0
- winDlg.style = CS_HREDRAW | CS_VREDRAW; //设置窗口格式,一般设置为水平重画与垂直重画:CS_HREDRAW | CS_VREDRAW
- winDlg.hIcon = LoadIcon(NULL, IDI_APPLICATION); //设置程序图标
- winDlg.hCursor = LoadCursor(NULL, IDC_ARROW); //设置程序光标
- winDlg.hbrBackground = (HBRUSH)GetStockObject(BLACK_PEN); //设置程序背景色:(HBRUSH)(COLOR_WINDOW + 1),(HBRUSH)GetStockObject(GRAY_BRUSH)
- //winDlg.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32UI); //设置菜单名称
- //winDlg.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); //
- winDlg.lpfnWndProc = WndTotalProc; //窗口的回调函数,也就是窗口接收到消息后,交给哪个函数处理
- if (hInstance) //程序实例,这里就用到了WinMain函数的第一个参数hInstance
- winDlg.hInstance = hInstance;
- else
- winDlg.hInstance = GetModuleHandle(NULL);
- return RegisterClassEx(&winDlg); //填入要注册的窗口结构
- }
- HWND SMachineDlg::OpenWindow(int nCmdShow)
- {
- m_hWnd = CreateWindow(
- m_strWindowClass.c_str(), //窗口类名,也就是上面注册窗口类时填的类名
- m_strTitle.c_str(), //窗口名,也就是窗口显示时,左上角显示的名称
- WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_SYSMENU, //窗口风格,一般填WS_OVERLAPPEDWINDOW即可,这样创建的窗口就有最大化,最小化等等等等属性
- CW_USEDEFAULT, //窗口最开始被创建位置,这里填X坐标,一般默认CW_USEDEFAULT即可
- CW_USEDEFAULT, //窗口最开始被创建位置,这里填Y坐标,一般默认CW_USEDEFAULT即可
- 100 * glo_BaseUnitX, //窗口创建的宽度,一般默认CW_USEDEFAULT即可
- 25 * glo_BaseUnitY, //窗口创建的高度,一般默认CW_USEDEFAULT即可
- NULL, //父窗口的句柄,没有,填NULL
- NULL, //菜单句柄,没有,填NULL
- GetModuleHandle(NULL), //应用程序实例,这里就又用到了WinMain的第一个参数
- NULL);//额外的数据,挺复杂的,咱们也不需要,填NULL就行了
- if (m_hWnd)
- {
- g_HandleDlgMap[m_hWnd] = this;
- ShowWindow(m_hWnd, nCmdShow); //显示窗口:SW_SHOWNORMAL
- if (UpdateWindow(m_hWnd)) //更新窗口客户区
- {
- m_ExitFlag = GetExitEvt();
- //添加界面元素
- CreateUIElement(m_hWnd);
- }
- }
- else
- {
- //mLog::FERROR("Create Window[{$}] failed", m_strTitle.c_str());
- }
- return m_hWnd;
- }
- void SMachineDlg::CreateUIElement(HWND& hMainWnd)
- {
- //创建元素
- auto FUN_CreateElement = [this, hMainWnd](int ID_Element) -> void
- {
- auto item = m_ElementMap.find(ID_Element);
- if (item != m_ElementMap.end())
- {
- if(nullptr == item->second.m_hHandle)
- item->second.m_hHandle = CreateWindow(
- item->second.m_strClassName.c_str(), item->second.m_strWindowName.c_str(),
- WS_CHILD | WS_VISIBLE | item->second.m_nStyle,
- item->second.m_nPosX * glo_BaseUnitX, item->second.m_nPosY * glo_BaseUnitY,
- item->second.m_nXsize * glo_BaseUnitX, item->second.m_nYsize * glo_BaseUnitY,
- hMainWnd,
- (HMENU)ID_Element,
- (HINSTANCE)GetWindowLongPtr(hMainWnd, GWLP_HINSTANCE),
- NULL);
- if (item->second.m_hHandle)
- {
- ShowWindow(item->second.m_hHandle, item->second.m_nShow);
- UpdateWindow(item->second.m_hHandle);
- }
- else
- {
- //mLog::FERROR("Create [{$}:{$}] failed", item->second.m_strClassName.c_str(), item->second.m_strWindowName.c_str());
- }
- }
- else
- {
- //mLog::FDEBUG("[{$}:{$}] already Create", item->second.m_strClassName.c_str(), item->second.m_strWindowName.c_str());
- }
- };
- m_ElementMap[Dlg_Button_ManualTriggered] = stuWindowElement("button", "ManualTriggered", BS_PUSHBUTTON, 1, 1, 20, 2, SW_SHOW);
- m_ElementMap[Dlg_Edit_ManualEventName] = stuWindowElement("edit", "ManualEventName", ES_MULTILINE, 27, 1, 20, 2, SW_SHOW);
- m_ElementMap[Dlg_Button_JumpToNext] = stuWindowElement("button", "JumpToNext", BS_PUSHBUTTON, 1, 4, 20, 2, SW_SHOW);
- m_ElementMap[Dlg_Edit_NextStateName] = stuWindowElement("edit", "NextStateName", ES_MULTILINE | ES_READONLY, 27, 4, 20, 2, SW_SHOW);
- m_ElementMap[Dlg_Radio_GroupJump] = stuWindowElement("button", "Auto or Manual Jump", BS_GROUPBOX, 0, 7, 48, 4, SW_SHOW);
- m_ElementMap[Dlg_Radio_ManualJump] = stuWindowElement("button", "AutoJump", BS_AUTORADIOBUTTON, 1, 8, 20, 2, SW_SHOW);
- m_ElementMap[Dlg_Radio_AutoJump] = stuWindowElement("button", "ManualJump", BS_AUTORADIOBUTTON, 27, 8, 20, 2, SW_SHOW);
- m_ElementMap[Dlg_Edit_WaitEventList] = stuWindowElement("edit", "WaitEventList", ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL, 49, 1, 48, 10, SW_SHOW);
- m_ElementMap[Dlg_Edit_RunHistory] = stuWindowElement("edit", "RunHistory", ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL, 1, 12, 96, 10, SW_SHOW);
- for (auto& item : m_ElementMap)
- {
- FUN_CreateElement(item.first);
- }
- }
- bool SMachineDlg::CloseWindow()
- {
- if (m_hWnd)
- {
- CallMap::iterator iter = g_HandleDlgMap.find(m_hWnd);
- if (iter != g_HandleDlgMap.end())
- {
- g_HandleDlgMap.erase(iter);
- }
- m_hWnd = nullptr;
- }
- return true;
- }
- bool SMachineDlg::OnStartThread()
- {
- //1.向系统注册一个窗体类
- RegisterWindowClass();
- //2.根据窗体类创建窗口
- return OpenWindow(SW_SHOW);
- }
- bool SMachineDlg::OnEndThread()
- {
- return CloseWindow();
- }
- bool SMachineDlg::Exec() //只会执行一次
- {
- MSG msg;
- while (WaitForSingleObject(m_ExitFlag, 0) == WAIT_TIMEOUT)
- {
- //3.进入消息循环
- if (GetMessage(&msg, //拿到的消息
- m_hWnd, //拿哪个窗口的消息,一般填NULL,即拿属于该线程所有窗口的消息
- 0, //过滤消息,最小值,一般填0
- 0) //过滤消息,最大值,一般填0,当两个均为0,则不进行过滤
- )
- {
- TranslateMessage(&msg); //消息转换,如将WMWM_KEYDOWN和WM_KEYUP翻译成一个WM_CHAR消息
- DispatchMessage(&msg); //该函数就是把消息派发给对应的窗口
- }
- else
- {
- return false;
- }
- }
- return false;
- }
- //窗口函数
- LRESULT SMachineDlg::WndTotalProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- CallMap::iterator iter = g_HandleDlgMap.find(hWnd);
- if (iter != g_HandleDlgMap.end())
- {
- switch (message)//通过判断消息进行消息响应
- {
- case WM_CREATE: //应用程序创建一个窗口
- {
- return 0;
- }break;
- case WM_DESTROY: //一个窗口被销毁
- {
- PostQuitMessage(0); //发出WM_QUIT消息,结束消息循环
- iter->second->StopThread();
- return 0;
- }break;
- case WM_CLOSE: //当一个窗口或应用程序要关闭时发送一个信号
- {
- DestroyWindow(hWnd); //销毁窗口并发送WM_DESTROY消息,但是程序没有退出
- return 0;
- }break;
- //case WM_PAINT:
- //{
- // PAINTSTRUCT ps;
- // RECT rect;
- // HDC hdc = BeginPaint(hWnd, &ps);
- // SetRect(&rect, 10, 10, 300, 200);
- // FrameRect(hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
- // GetClientRect(hWnd, &rect);
- // rect.left += 20;
- // rect.top += 2;
- // //SetTextColor(hdc, RGB(255,0,0)); //可以用RGB三原色设置文本颜色
- // DrawText(hdc, TEXT(" Hello, Dev-C++! "), -1, &rect, DT_SINGLELINE | DT_TOP | DT_LEFT);
- // EndPaint(hWnd, &ps);
- // return 0;
- //}break;
- case WM_COMMAND: //各控件的_click()事件
- {
- switch (LOWORD(wParam)) {
- case LOWORD(Dlg_Button_ManualTriggered):
- {
- if (iter->second->m_DlgCallback)
- {
- // 获取编辑控件的文本长度
- int length = GetWindowTextLength(iter->second->m_ElementMap[Dlg_Edit_ManualEventName].m_hHandle) + 1;
- // 创建一个字符串缓冲区
- std::vector<char> buffer(length);
- // 获取编辑控件的文本
- GetWindowText(iter->second->m_ElementMap[Dlg_Edit_ManualEventName].m_hHandle, buffer.data(), length);
- string temp = buffer.data();
- iter->second->m_DlgCallback("TriggerEvent", temp);
- }
- return 0;
- }break;
- case LOWORD(Dlg_Button_JumpToNext):
- {
- if (iter->second->m_DlgCallback)
- {
- iter->second->m_DlgCallback("SetRunningState", "");
- }
- return 0;
- }break;
- case LOWORD(Dlg_Radio_ManualJump):
- {
- iter->second->SetJumpMode(1);
- return 0;
- }break;
- case LOWORD(Dlg_Radio_AutoJump):
- {
- iter->second->SetJumpMode(0);
- return 0;
- }break;
- }
- }break;
- #if 0 //调试使用
- case WM_LBUTTONDOWN: // WM_LBUTTONDOWN是鼠标左键按下的事件
- {
- POINT mouse;
- RECT rect;
- GetCursorPos(&mouse);
- GetWindowRect(hWnd, &rect);
- int mX = mouse.x - rect.left;
- int mY = mouse.y - rect.top;
- char x[5]{ 0 }, y[5]{ 0 };
- _itoa(mX, x, 10);
- _itoa(mY, y, 10);
- string strXy = "坐标(" + string(x) + "," + string(y) + ")";
- SetWindowText(iter->second->m_ElementMap[Dlg_Edit_ManualEventName].m_hHandle, strXy.c_str());
- return 0;
- }break;
- #endif
- }
- }
- return DefWindowProc(hWnd, message, wParam, lParam); //对不感兴趣的消息进行缺省处理,必须有该代码,否则程序有问题
- }
- void SMachineDlg::SetJumpMode(int mode)
- {
- switch (mode)
- {
- case 0: //auto
- {EnableWindow(m_ElementMap[Dlg_Button_JumpToNext].m_hHandle, FALSE);
- EnableWindow(m_ElementMap[Dlg_Edit_NextStateName].m_hHandle, FALSE);
- SendMessage(m_ElementMap[Dlg_Radio_ManualJump].m_hHandle, BM_SETCHECK, 0, 0);
- SendMessage(m_ElementMap[Dlg_Radio_AutoJump].m_hHandle, BM_SETCHECK, 1, 0);
- }break;
- case 1: //manual
- {
- EnableWindow(m_ElementMap[Dlg_Button_JumpToNext].m_hHandle, TRUE);
- EnableWindow(m_ElementMap[Dlg_Edit_NextStateName].m_hHandle, TRUE);
- SendMessage(m_ElementMap[Dlg_Radio_ManualJump].m_hHandle, BM_SETCHECK, 1, 0);
- SendMessage(m_ElementMap[Dlg_Radio_AutoJump].m_hHandle, BM_SETCHECK, 0, 0);
- }break;
- default:
- break;
- }
- }
- void SMachineDlg::SetWaitEventList(string& text)
- {
- SetWindowText(m_ElementMap[Dlg_Edit_WaitEventList].m_hHandle, text.c_str());
- }
- void SMachineDlg::SetRunHistory(string& text)
- {
- SetWindowText(m_ElementMap[Dlg_Edit_RunHistory].m_hHandle, text.c_str());
- }
|