Từ 1 tới 5 trên tổng số 5 kết quả

Đề tài: có bạn nào làm đc ControlClick giống như bên AutoIT?

  1. #1
    Ngày gia nhập
    06 2017
    Bài viết
    18

    Mặc định có bạn nào làm đc ControlClick giống như bên AutoIT?

    Tôi đã thử với 2 cách:
    1)mouse_event
    Sử dụng đc nhưng chiếm Mouse.

    2) PostMessage hoặc SendMessage
    PostMessage(h, WM_MOUSEMOVE, 0, lParam);
    PostMessage(h, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
    PostMessage(h, WM_LBUTTONUP, MK_LBUTTON, lParam);
    Không sử dụng đc.

    Có cách nào giống hàm ControlClick bên AutoIt, không chiếm Mouse, cửa sổ ứng dụng nhận Mouse không cần focus.

  2. #2
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    684

    Bạn hoàn toàn có thể làm được, nhưng chú ý vài điểm sau :
    _ Đặt tham số wParam và lParam phải thật chính xác, nhất là tham số lParam - có lẽ bạn chưa làm được vì đặt lParam chưa đúng.
    _ Nếu cửa sổ mà ta mô phỏng Click trên nó mà không chuyển focus cho nó thì với vài điều khiển nó xử lý không đẹp lắm. Ví dụ : Bạn muốn Click vào một hộp Edit (Textbox) mà không chuyển Focus thì con nháy (Caret) sẽ không xuất hiện trên Edit - trông sẽ giống như chương trình chạy sai.
    _ Khi bạn muốn Click vào một điều khiển A tại 1 điểm POINT, nhưng điểm này lại có 1 điều khiển con B là con của A đang ở tại vị trí đó, Send hoặc Post sẽ không có ý nghĩa gì. Vì vậy bạn nên tìm cửa sổ trên cùng để Click.
    Yêu mã hơn yêu em !!!

  3. #3
    Ngày gia nhập
    06 2017
    Bài viết
    18

    LPARAM lParam = x | (y << 16);
    tham số này mình biết cách đặt mà: LOWORD là x, HIWORD là y.
    Sử dụng trong trường hợp Click Button thôi.
    Đặt rồi nhưng nó không chạy. Không tự Click đc, mình cũng hiểu cách lấy HWND vì đã từng viết auto Volamtruyenky (sử dụng autoit viết code) trên giả lập Điện thoại và sử dụng tốt. Vì mình cần tốc độ của C nên đang tìm hiểu.

  4. #4
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    684

    Viết tốc hành một mẫu tham khảo cho bạn : Chỉ duy nhất 1 tập tin cpp trên dự án trống cho VS.
    C++ Code:
    1. #include <windows.h>
    2. #include <vector>
    3. #include <commctrl.h>
    4. #pragma comment(lib, "comctl32.lib")
    5.  
    6. #define     IDC_LISTVIEW                20000
    7. #define     IDC_BUTTON_RELOAD           20001
    8. #define     IDC_BUTTON_CONTROLCLICK     20002
    9. #define     MINWINDOWWIDTH              400
    10. #define     MINWINDOWHEIGHT             400
    11.  
    12. typedef struct
    13. {
    14.     HWND        hTree;          // Treeview chương trình
    15.     HWND        hParent;        // Cửa sổ cha của cửa sổ đang xét
    16.     HTREEITEM   hParentItem;    // Item cha
    17. } ITEMPARAM, *PITEMPARAM;
    18. typedef struct
    19. {
    20.     HWND        hTree;              // Treeview chứa các cửa sổ đang hiện diện trên màn hình
    21.     HWND        hbtReload;          // Button dùng để đếm trở lại các cửa sổ
    22.     HWND        hbtControlClick;    // Button mô phỏng hàm ControlClick của AutoIt
    23. } HWNDS, *PHWNDS;
    24.  
    25. HWND Find(HWND hThis, POINT ptCursor)
    26. {
    27.     RECT                r;
    28.     HWND                hAnother;
    29.     std::vector<HWND>   vtHwnd;
    30.  
    31.     hAnother = hThis;                                   // Cửa sổ cùng cấp đầu tiên
    32.     vtHwnd.push_back(hAnother);                         // Lưu lại
    33.     do
    34.     {
    35.         hAnother = GetWindow(hAnother, GW_HWNDNEXT);
    36.         if (hAnother)                                   // Một cửa sổ cùng cấp khác
    37.             vtHwnd.push_back(hAnother);                 // Lưu lại
    38.     } while (hAnother);
    39.  
    40.     HWND    hReturn = NULL;
    41.     for (std::vector<HWND>::iterator i = vtHwnd.begin(); i != vtHwnd.end(); i++)
    42.     {
    43.         GetWindowRect(*i, &r);
    44.         if (PtInRect(&r, ptCursor))                     // Chuột nằm trong cửa sổ này
    45.         {
    46.             HWND    hChild = GetWindow(*i, GW_CHILD);
    47.             if (hChild)                                 // Nếu tồn tại cửa sổ con
    48.             {
    49.                 HWND    hFind = Find(hChild, ptCursor);
    50.                 if (hFind)
    51.                     return hFind;
    52.                 else
    53.                     return hThis;
    54.             }
    55.             return hThis;
    56.         }
    57.     }
    58.     return NULL;
    59. }
    60. void ControlClick(HWND hwnd)
    61. {
    62.     RECT    r;
    63.     GetWindowRect(hwnd, &r);
    64.     POINT   ptCursor;
    65.     ptCursor.x = r.left + (r.right - r.left) / 2;
    66.     ptCursor.y = r.top + (r.bottom - r.top) / 2;
    67.     // Chúng ta mô phỏng Click tại điểm này của 1 cửa sổ hwnd nhưng nếu tại điểm này lại
    68.     // lọt vào vùng cửa sổ của một điều khiển con hChild của hwnd thì các thông điệp
    69.     // gởi tới hwnd sẽ sai. Vì vậy ta phải tìm cửa sổ con mà nằm trên cùng (trong Z index)
    70.     // để gởi thông điệp tới.
    71.     HWND    hLast;
    72.     if (GetParent(hwnd))                    // Không phải cửa sổ đỉnh
    73.         hLast = Find(hwnd, ptCursor);
    74.     else                                    // Là cửa sổ mức đỉnh
    75.     {
    76.         hLast = GetWindow(hwnd, GW_CHILD);
    77.         if (hLast)
    78.             hLast = Find(hLast, ptCursor);
    79.         if (!hLast)
    80.             hLast = hwnd;
    81.     }
    82.  
    83.     ScreenToClient(hLast, &ptCursor);
    84.     /////////////////////// Các lệnh mô phỏng Click chuột ở đây /////////////////////////////
    85.     LPARAM  lparam = MAKELPARAM(ptCursor.x, ptCursor.y);
    86.     PostMessage(hLast, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
    87.     PostMessage(hLast, WM_LBUTTONUP, 0, lparam);
    88.     /////////////////////////////////////////////////////////////////////////////////////////
    89. }
    90. HTREEITEM AddTreeItem(HWND hTree, PCHAR szItem, HWND hwnd, HTREEITEM hParentItem)
    91. {
    92.     TVITEM              tvi;
    93.     TVINSERTSTRUCT      tvins;
    94.  
    95.     tvi.mask = TVIF_TEXT | TVIF_PARAM;
    96.     tvi.pszText = szItem;
    97.     tvi.cchTextMax = sizeof(tvi.pszText) / sizeof(tvi.pszText[0]);
    98.     tvi.lParam = (LPARAM)hwnd;
    99.     tvins.item = tvi;
    100.     tvins.hInsertAfter = TVI_LAST;
    101.     tvins.hParent = hParentItem;
    102.  
    103.     return (HTREEITEM)SendMessage(hTree, TVM_INSERTITEM, 0, (LPARAM)&tvins);
    104. }
    105. BOOL CALLBACK EnumChildProc(HWND hChild, LPARAM lparam)
    106. {
    107.     PITEMPARAM  pItemParam = (PITEMPARAM)lparam;
    108.     // Lọc bớt các cửa sổ đếm không theo phân cấp
    109.     if (GetParent(hChild) != pItemParam->hParent)
    110.         return TRUE;
    111.     // Lọc bỏ bớt các cửa sổ không hiển thị
    112.     if (!IsWindowVisible(hChild))
    113.         return TRUE;
    114.     // Lọc bỏ bớt các cửa sổ không kích thước
    115.     RECT    r;
    116.     GetWindowRect(hChild, &r);
    117.     if (r.right - r.left == 0 || r.bottom - r.top == 0)
    118.         return TRUE;
    119.     CHAR    szItem[MAX_PATH * 2], szName[MAX_PATH], szClass[MAX_PATH];
    120.     GetClassName(hChild, szClass, MAX_PATH - 1);
    121.     int     iLength = GetWindowTextLength(hChild);
    122.     if (iLength)
    123.     {
    124.         GetWindowText(hChild, szName, MAX_PATH - 1);
    125.         wsprintf(szItem, "%p - <%s> - %s", hChild, szName, szClass);
    126.     }
    127.     else
    128.         wsprintf(szItem, "%p - <NULL> - %s", hChild, szClass);
    129.     HTREEITEM   hItem = AddTreeItem(pItemParam->hTree, szItem, hChild, pItemParam->hParentItem);
    130.     // Đếm các cửa sổ con của cửa sổ này - Chỉ đếm 1 cấp
    131.     ITEMPARAM   ItemParam = { pItemParam->hTree, hChild, hItem };
    132.     EnumChildWindows(hChild, EnumChildProc, (LPARAM)&ItemParam);
    133.     return TRUE;
    134. }
    135. BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    136. {
    137.     PITEMPARAM  pItemParam = (PITEMPARAM)lparam;
    138.     // Lọc bỏ bớt các cửa sổ không hiển thị
    139.     if (!IsWindowVisible(hwnd))
    140.         return TRUE;
    141.     // Lọc bỏ bớt các cửa sổ đang thu nhỏ thành Icon trên thanh Taskbar
    142.     if (IsIconic(hwnd))
    143.         return TRUE;
    144.     // Lọc bỏ bớt các cửa sổ không kích thước
    145.     RECT    r;
    146.     GetWindowRect(hwnd, &r);
    147.     if (r.right - r.left == 0 || r.bottom - r.top == 0)
    148.         return TRUE;
    149.     // Lọc bỏ bớt các cửa sổ không có text Caption
    150.     int     iLength = GetWindowTextLength(hwnd);
    151.     if (!iLength)
    152.         return TRUE;
    153.     CHAR    szItem[MAX_PATH * 2], szName[MAX_PATH], szClass[MAX_PATH];
    154.     GetClassName(hwnd, szClass, MAX_PATH - 1);
    155.     GetWindowText(hwnd, szName, MAX_PATH - 1);
    156.     wsprintf(szItem, "%p - <%s> - %s", hwnd, szName, szClass);
    157.     HTREEITEM   hItem = AddTreeItem(pItemParam->hTree, szItem, hwnd, NULL);
    158.     // Đếm các cửa sổ con của cửa sổ này - Chỉ đếm 1 cấp
    159.     ITEMPARAM   ItemParam = { pItemParam->hTree, hwnd, hItem };
    160.     EnumChildWindows(hwnd, EnumChildProc, (LPARAM)&ItemParam);
    161.     return TRUE;
    162. }
    163. LRESULT OnCreate(HINSTANCE hInst, HWND hwnd, PHWNDS phwnds)
    164. {
    165.     phwnds->hTree = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME, WC_TREEVIEW, "Treeview HWND", WS_VISIBLE | WS_CHILD | WS_BORDER |
    166.         TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS, 0, 0, 0, 0, hwnd, (HMENU)IDC_LISTVIEW, hInst, NULL);
    167.     phwnds->hbtReload = CreateWindow("button", "Reload", WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd, (HMENU)IDC_BUTTON_RELOAD, hInst, NULL);
    168.     phwnds->hbtControlClick = CreateWindow("button", "ControlClick", WS_DISABLED | WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd, (HMENU)IDC_BUTTON_CONTROLCLICK, hInst, NULL);
    169.     TreeView_SetBkColor(phwnds->hTree, RGB(0, 255, 255));
    170.     return 0;
    171. }
    172. LRESULT OnSizing(PRECT pRect)
    173. {
    174.     LRESULT     rs = 0;
    175.     if (pRect->right - pRect->left < MINWINDOWWIDTH)
    176.     {
    177.         pRect->right = pRect->left + MINWINDOWWIDTH;
    178.         rs = 1;
    179.     }
    180.     if (pRect->bottom - pRect->top < MINWINDOWHEIGHT)
    181.     {
    182.         pRect->bottom = pRect->top + MINWINDOWHEIGHT;
    183.         rs = 1;
    184.     }  
    185.     return rs;
    186. }
    187. LRESULT OnSize(LPARAM lparam, PHWNDS phwnds)
    188. {
    189.     int cxClient = LOWORD(lparam);
    190.     int cyClient = HIWORD(lparam);
    191.     MoveWindow(phwnds->hTree, 20, 20, cxClient - 40, cyClient - 75, TRUE);
    192.     MoveWindow(phwnds->hbtReload, cxClient / 2 - 105, cyClient - 45, 100, 25, TRUE);
    193.     MoveWindow(phwnds->hbtControlClick, cxClient / 2 + 5, cyClient - 45, 100, 25, TRUE);
    194.     return 0;
    195. }
    196. LRESULT OnNotify(HWND hwnd, WPARAM wparam, LPARAM lparam, PHWNDS phwnds)
    197. {
    198.     switch (((LPNMHDR)lparam)->code)
    199.     {
    200.     case TVN_SELCHANGED:
    201.         EnableWindow(phwnds->hbtControlClick, ((LPNMTREEVIEW)lparam)->itemNew.hItem ? TRUE : FALSE);
    202.         return 0;
    203.     }
    204.     return DefWindowProc(hwnd, WM_NOTIFY, wparam, lparam);
    205. }
    206. LRESULT OnCommand(HWND hwnd, WPARAM wparam, LPARAM lparam, PHWNDS phwnds)
    207. {
    208.     ITEMPARAM           ItemParam;
    209.     TVITEM              tvi;
    210.  
    211.     switch (LOWORD(wparam))
    212.     {
    213.     case IDC_BUTTON_RELOAD:
    214.         TreeView_DeleteAllItems(phwnds->hTree);
    215.         ItemParam.hParent = NULL;
    216.         ItemParam.hParentItem = NULL;
    217.         ItemParam.hTree = phwnds->hTree;
    218.         EnumWindows(EnumWindowsProc, (LPARAM)&ItemParam);
    219.         SetFocus(phwnds->hTree);
    220.         return 0;
    221.     case IDC_BUTTON_CONTROLCLICK:
    222.         tvi.mask = TVIF_PARAM;
    223.         tvi.hItem = TreeView_GetSelection(phwnds->hTree);
    224.         TreeView_GetItem(phwnds->hTree, &tvi);
    225.         if ((HWND)tvi.lParam == phwnds->hbtControlClick)
    226.         {
    227.             MessageBox(hwnd, "Error : Click at <ControlClick> !!!\nLoop...", "Error", MB_OK | MB_ICONEXCLAMATION);
    228.             return 0;
    229.         }
    230.         ControlClick((HWND)tvi.lParam);
    231.         return 0;
    232.     }
    233.     return DefWindowProc(hwnd, WM_COMMAND, wparam, lparam);
    234. }
    235. LRESULT OnClose(HWND hwnd)
    236. {
    237.     if (IDYES == MessageBox(hwnd, "Sure close ?", "Confirm", MB_YESNO | MB_ICONQUESTION))
    238.         DestroyWindow(hwnd);
    239.     return 0;
    240. }
    241. LRESULT OnDestroy()
    242. {
    243.     PostQuitMessage(0);
    244.     return 0;
    245. }
    246. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    247. {
    248.     static  HWNDS       hwnds;      // Những cửa sổ
    249.  
    250.     switch (message)
    251.     {
    252.     case WM_CREATE:     return OnCreate(((LPCREATESTRUCT)lparam)->hInstance, hwnd, &hwnds);
    253.     case WM_SIZING:     return OnSizing((PRECT)lparam);
    254.     case WM_SIZE:       return OnSize(lparam, &hwnds);
    255.     case WM_NOTIFY:     return OnNotify(hwnd, wparam, lparam, &hwnds);
    256.     case WM_COMMAND:    return OnCommand(hwnd, wparam, lparam, &hwnds);
    257.     case WM_CLOSE:      return OnClose(hwnd);
    258.     case WM_DESTROY:    return OnDestroy();
    259.     }
    260.     return DefWindowProc(hwnd, message, wparam, lparam);
    261. }
    262. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
    263. {
    264.     WNDCLASS    wc;
    265.     wc.cbClsExtra = 0;
    266.     wc.cbWndExtra = 0;
    267.     wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
    268.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    269.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    270.     wc.hInstance = hInstance;
    271.     wc.lpfnWndProc = WndProc;
    272.     wc.lpszClassName = "ControlClick";
    273.     wc.lpszMenuName = NULL;
    274.     wc.style = CS_HREDRAW | CS_VREDRAW;
    275.     if (!RegisterClass(&wc))
    276.         return 0;
    277.     HWND    hwnd = CreateWindow(wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, MINWINDOWWIDTH, MINWINDOWHEIGHT, NULL, NULL, hInstance, NULL);
    278.     if (!hwnd)
    279.         return 0;
    280.     ShowWindow(hwnd, nCmdShow);
    281.     UpdateWindow(hwnd);
    282.     MSG msg;
    283.     while (GetMessage(&msg, NULL, 0, 0))
    284.     {
    285.         TranslateMessage(&msg);
    286.         DispatchMessage(&msg);
    287.     }
    288.     return msg.wParam;
    289. }

    Lúc nào rảnh, mình sẽ nhờ bạn trợ giúp cho vài chiêu trên DĐ, bạn sẵn lòng chứ. hì hì. Chào bạn
    Yêu mã hơn yêu em !!!

  5. #5
    Ngày gia nhập
    06 2017
    Bài viết
    18

    MouseClick đã làm đc rồi. Thank bạn MHoang!
    Nhưng lại có thắc mắc thêm , nếu Cửa sổ chuơng trình hiện bình thường (không cần focus) thì MouseClick hoạt động đc NHƯNG Cửa sổ chuơng trình bị thu nhỏ xuống khay Taskbar thì pó tay. Có cách khắc phục đc không bạn?
    Đang viết auto VoLamMobi lại bị vướng phần PostMessage nhập Key, nó không chịu nhập. Hic

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn