1. Tải bản cài đặt AutoIT mới nhất

    Chào Khách. Nếu bạn mới tham gia và chưa cài đặt AutoIT.
    Vui lòng vào topic trên để tải bản AutoIT mới nhất nhé
    Dismiss Notice
  2. Quy định và nội quy

    Chào Khách. Vui lòng đọc kỹ nội quy và quy định của diễn đàn
    Để tránh bị ban một cách đáng tiếc nhé!
    Dismiss Notice
  3. Hướng dẫn chèn mã AutoIT trong diễn đàn

    Chào Khách. Vui lòng xem qua bài viết này
    Để biết cách chèn mã AutoIT trong diễn đàn bạn nhé :)
    Dismiss Notice

Hướng dẫn Tạo GUI bằng WinAPI (library win32)

Thảo luận trong 'Hướng dẫn - Bài tập nâng cao' bắt đầu bởi wuuyi123, 18/11/17.

  1. wuuyi123

    wuuyi123 Thành viên
    • 18/23

    Tham gia ngày:
    18/6/16
    Bài viết:
    54
    Đã được thích:
    98
    - Bạn thấy GUI của AutoIt quá cùi (class AutoIt v3 GUI), quá nhàm chán khi chỉ có thể chạy đơn luồng, không thể tương tác dễ dàng nếu đang trong vòng lặp hoặc đang chạy một hàm hay những cái nặng nề và ngốn tài nguyên... Để vượt qua khỏi giới hạn ấy, có một cách cũng rất đơn giản, nhưng lại ít người dùng đến, đó chính là WinAPI (hay Win32 library). Chắc chắn nghe cũng không xa lạ gì, đặc biệt đối với những bạn học C/C++, C#, Java... để build Windows App cơ bản đều dùng đến (thử tạo một project Window Desktop trong Visual Studio sẽ thấy). Ưu điểm của phương pháp này là vô cùng lớn.

    - Có thể nói là ta đã tạo ra thêm 1 Thread chạy song song với Thread cơ bản của AutoIt. Có thể chạy song song các hàm với nhau. Phá vỡ quy luật code line-by-line của AutoIt (tạm thời nói vậy đi ). cho ví dụ cụ thể như này: Bạn tạo một GUI trong Koda, thêm một cái Button nho nhỏ, sau đó insert code vào, set cho Button đó một cái lệnh MsgBox(...gì gì đó...)Run, sau đó bạn nhấn vào Button ấy và thấy một thông báo hiện lên, nhấn tiếp Button đó thì chương trình lại không hoạt động mà bắt buộc bạn phải đóng cái thông báo ấy mới chịu tiếp tục... quá bất tiện phải không nào, nhưng khi tạo bằng WinAPI thì bạn cứ vô tư, nhấn 20 lần ra 20 thông báo liên tục mà chương trình vẫn không lỗi tí nào. Thật vi diệu phải không...
    - Vào http://msdn.microsoft.com tìm hiểu thêm.


    Ảnh demo:
    [​IMG]

    [​IMG]


    Còn đây là App đã qua design:
    [​IMG]

    [​IMG]



    Mã (AutoIt):
    #include <WinAPIRes.au3>
    #include <WinAPISys.au3>
    #include <WindowsConstants.au3>

    ; http://msdn.microsoft.com
    Local Const $sClass = 'MyCustomClassName' ; Tên class name cho window
    Local Const $sName = 'Test Win32 GUI' ; Tên tiêu đề window

    Global $bExit = False

    ; Lấy module handle ~ 0
    Local $hInstance = _WinAPI_GetModuleHandle(0)

    ; Load cursor cho window
    Local $hCursor = _WinAPI_LoadCursor(0, 32512) ; IDC_ARROW = standard cursor (arrow)

    ; Tạo icon cho window
    Local $tIcons = DllStructCreate('ptr;ptr')
    _WinAPI_ExtractIconEx(@SystemDir & '\shell32.dll', 15, DllStructGetPtr($tIcons, 1), DllStructGetPtr($tIcons, 2), 1)
    Local $hIcon = DllStructGetData($tIcons, 1)
    Local $hIconSm = DllStructGetData($tIcons, 2)

    ; Tạo DLL Callback; return: LRESULT, param: HWND, UINT, WPARAM, LPARAM
    Local $hProc = DllCallbackRegister('WINPROC', 'lresult', 'hwnd;uint;wparam;lparam')

    ; Tạo DLL cấu trúc dữ liệu cho window class, xem trên MSDN dể hiểu rõ hơn
    Local $tWCEX = DllStructCreate($tagWNDCLASSEX & ';wchar szClassName[' & (StringLen($sClass) + 1) & ']')
    DllStructSetData($tWCEX, 'Size', DllStructGetPtr($tWCEX, 'szClassName') - DllStructGetPtr($tWCEX))
    DllStructSetData($tWCEX, 'Style', BitOR(0x0001,0x0002, 0x20000)) ; style cho window, 0x20000 kèm thêm shadow của class #32768 (class của popupmenu)
    DllStructSetData($tWCEX, 'hWndProc', DllCallbackGetPtr($hProc))
    DllStructSetData($tWCEX, 'ClsExtra', 0)
    DllStructSetData($tWCEX, 'WndExtra', 0)
    DllStructSetData($tWCEX, 'hInstance', $hInstance)
    DllStructSetData($tWCEX, 'hIcon', $hIcon) ; icon
    DllStructSetData($tWCEX, 'hCursor', $hCursor) ; cursor
    DllStructSetData($tWCEX, 'hBackground', _WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_3DFACE)))
    DllStructSetData($tWCEX, 'MenuName', 0)
    DllStructSetData($tWCEX, 'ClassName', DllStructGetPtr($tWCEX, 'szClassName'))
    DllStructSetData($tWCEX, 'hIconSm', $hIconSm)
    DllStructSetData($tWCEX, 'szClassName', $sClass) ; class namme

    ; đăng ký class cho window
    _WinAPI_RegisterClassEx($tWCEX)

    ; tạo window mới với class vừa tạo
    Global $hGUI = _WinAPI_CreateWindowEx(0, $sClass, $sName, BitOR($WS_CAPTION, $WS_POPUPWINDOW, $WS_VISIBLE, 0x00CF0000), (@DesktopWidth - 400) / 2, (@DesktopHeight - 400) / 2, 400, 400, 0)


    ; Tạo button từ class "button" có sẵn trong windows-ms
    Global $hButton1 = _WinAPI_CreateWindowEx(0, "Button", "Button 1", BitOR($WS_CHILD, $WS_VISIBLE), 40, 40, 100, 35, $hGUI)
    Global $hButton2 = _WinAPI_CreateWindowEx(0, "Button", "Button 2", BitOR($WS_CHILD, $WS_VISIBLE), 40, 80, 100, 35, $hGUI)



    While 1
        Sleep(10) ; Nhớ đặt sleep hoặc bất kỳ thứ gì trong While...Wend để tránh lỗi ngốn CPU
        If $bExit Then
            ExitLoop
        EndIf
    WEnd

    ; Xóa class vừa đăng ký, release icon/cursor..., không có cũng không sao
    _WinAPI_UnregisterClass($sClass, $hInstance)
    _WinAPI_DestroyCursor($hCursor)
    _WinAPI_DestroyIcon($hIcon)
    _WinAPI_DestroyIcon($hIconSm)

    DllCallbackFree($hProc)

    ; Callback của window (WINPROC), trong hàm này sẽ xử lý song song với thread của AutoIt
    ; Hàm này sẽ không bị dừng khi dùng vòng lặp (while, do, for...), có thể tương tác bất kỳ lúc nào
    ; Nếu dùng sleep thì toàn bộ chương trình sẽ dừng lại
    Func WINPROC($hWnd, $iMsg, $wParam, $lParam)

        Switch $iMsg ; đọc message của window gửi tới và xử lý
            Case $WM_CLOSE ; khi nhấn close (nút X) thì procedure nhận

                $bExit = True ; set true để dòng trên While thoát chương trình
            Case $WM_COMMAND ; lệnh command khi tương tác với window

                Switch $lParam ; lparam sẽ trả về handle của control đó
                    Case $hButton1
                        MsgBox(0, "", "You clicked Button 1")
                    Case $hButton2
                        MsgBox(0, "", "You clicked Button 2")
                ; Bạn có thể nhấn liên tục vào các Button mà không bị dừng lại, mặc dù các thông báo liên tục xuất ra


                EndSwitch
        EndSwitch

        Return _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) ; phải bắt buộc define cho window để không bị lỗi
    EndFunc
     
     
  2. Huân Hoàng

    Huân Hoàng Administrator Thành viên BQT Administrator Super Moderator
    • 93/113

    Tham gia ngày:
    29/9/15
    Bài viết:
    642
    Đã được thích:
    1,181
    Chất lượng quá thým ơi :autoit:
     
  3. tuoitre

    tuoitre Thành viên năng động
    • 28/34

    Tham gia ngày:
    15/9/15
    Bài viết:
    135
    Đã được thích:
    89
    Iêm phải đăng nhập để like cho bác thớt :v
     
  4. JK. KyTs

    JK. KyTs I'm Hiếu Võ Văn
    • 28/34

    Tham gia ngày:
    7/9/15
    Bài viết:
    20
    Đã được thích:
    161
    Nơi ở:
    Quang Nam
    Kỹ thuật mới này nghe hay đấy :))
     
  5. dvhtrung

    dvhtrung Thành viên mới
    • 1/6

    Tham gia ngày:
    15/7/17
    Bài viết:
    11
    Đã được thích:
    0
    Nếu mình chỉ tạo 1 button bằng winapi để chạy while wend và muốn 1 nút để tắt while đó thì làm thế nào hả bác
     
  6. DuyMinh

    DuyMinh Thành viên năng động
    • 28/34

    Tham gia ngày:
    14/3/17
    Bài viết:
    177
    Đã được thích:
    92
    Bác có thể cho mình xin ví dụ khi làm multi-gui không?
     
  7. wuuyi123

    wuuyi123 Thành viên
    • 18/23

    Tham gia ngày:
    18/6/16
    Bài viết:
    54
    Đã được thích:
    98
    Multi GUI thì bạn dùng nhiều hàm CreateWindowEx, rồi tạo ra nhiều class để dễ quản lý. Nếu dùng chung class thì phải thông quan HWND để phân biệt chúng.
     
  8. tamle2289

    tamle2289 Thành viên mới
    • 1/6

    Tham gia ngày:
    12/5/18
    Bài viết:
    9
    Đã được thích:
    0
    làm kiểu gì để có cái gui như ảnh dưới qua design ấy bác
     
  9. wuuyi123

    wuuyi123 Thành viên
    • 18/23

    Tham gia ngày:
    18/6/16
    Bài viết:
    54
    Đã được thích:
    98
    Nếu bạn thích thì mình share luôn source, cái này định thay luôn cho scite nhưng mà bận nên dở dang nữa chừng mình cũng không viết tiếp được (gần 1 năm rồi), có kết hợp cả C++ vào để cải thiện hiệu năng.

    Pass: 123
    Chạy file main.au3, muốn build thì chuột phải vào file build.au3, chọn Compile Script.
     

    Các file đính kèm:

    Huân Hoàng, tamle2289 and Flash like this.
  10. tamle2289

    tamle2289 Thành viên mới
    • 1/6

    Tham gia ngày:
    12/5/18
    Bài viết:
    9
    Đã được thích:
    0
    Cảm ơn bác nha :3
     
  11. luffysama

    luffysama Thành viên mới
    • 1/6

    Tham gia ngày:
    2/10/21
    Bài viết:
    3
    Đã được thích:
    0
    Mình thử đặt 2 vòng lặp vào 2 button. Sau khi nhấn button 1 thì vòng lặp thứ nhất chạy. Nhưng sau khi nhấn thêm button 2 thì chỉ có vòng lặp 2 chạy, vòng lặp 1 đã ngừng. Có cách nào để duy trì cả 2 vòng lặp song song không ạ
     

Chia sẻ trang này

Đang tải...