Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[TUT] Graficzny Interfejs Użytkownika


Rekomendowane odpowiedzi

Opublikowano

Witam
Na wstępie aby rozwiać wątpliwości GUI (ang. Graphical User Interface) - Graficzny interfejs użytkownika.

W tym tutorialu pokażę jak wykonać kilka rodzajów okien w AutoIt.
Aby jednak rozpocząć zabawę będzie nam potrzebny program Koda Form Designer który można pobrać tutaj
Zabawę rozpoczniemy od obrazka .gif
guid.th.gif
Nie ma jednorożcy :<
Najprościej zrobić jakiś obrazek .png, a później wrzucić go na jednobarwne tło(0xbfffbf u mnie). Koda nie obsługuje formatu png (tylko jpg, jpeg, bmp oraz gif, z czego gif zachowuje najlepszą jakość kolorów :)

Ponadto należy pamiętać, aby dla tła dobrać taki kolor który nie występuje w obrazku gdyż na koniec możemy zostać niemile zaskoczeni przez dziury ^^

OnEvent lub standardowy MessageLoop

MessageLoop pozostawimy na inny tutorial więc zajmiemy się GUIOnEventMode najprościej będzie to pokazać z przykładowym kodem.

Bez GUIOnEventMode wygląda to mniej-więcej tak:

$GUI=GuiCreate(...
$Control1=GuiCtrlCreate(...
$Control2=GuiCtrlCreate(...
;...
$ControlN=Guictrlcreate(...

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $Control1
_Action1()
Case $Control2
_Action2()
Case $Control3
_Action3()
Case $Control4
_Action4()
Case $Control5
_Action5()
WEnd



Po dodaniu GUIOnEventMode wygląda to tak:
Opt("GuiOnEventMode", 1)
$GUI=GuiCreate(...
$Control1=GuiCtrlCreate(...
$Control2=GuiCtrlCreate(...
;...
$ControlN=Guictrlcreate(...

For $i = $Control1 To $ControlN
GUICtrlSetOnEvent($i, '_Control_EVENT')
Next

While 1
sleep(10)
Wend

Func _Control_Event()
Switch @GUI_CtrlId
Case $Control1
_Action1()
Case $Control2
_Action2()
Case $Control3
_Action3()
Case $Control4
_Action4()
Case $Control5
_Action5()
Case $Control6, $Control7, $Control8, $ControlN
_ActionN()
Endswitch
Endfunc



Budowa obu kodów wygląda podobnie. Każda kontrolka może mieć własną funkcję (jak powyżej), można również użyć tej samej funkcji do każdej kontrolki. Pozwala to zachować przejrzystość skryptu i oszczędzi nam miejsca.

Przejdźmy teraz do stworzenia naszego GUI wraz z przyciskami :)
Dla tych co nie mieli styczności z programem Koda krótka instrukcja:
obrazdodaj.th.png
Numerki a obrazku odpowiadają tym poniżej:
  • Wybieramy zakładkę "Additional"
  • Wybieramy ikonę "Picture"
  • Klikamy w naszym polu roboczym, tworzy się nowy objekt
  • Zmieniamy szerokość (width) oraz wysokość (height) na wymiary naszego obrazka
  • W polu picture klikamy [...]
  • W oknie które nam wyskoczy (Picture Editor) naciskamy klawisz Load...
  • Wybieramy obrazek który ma zostać użyty
  • Naciskamy przycisk Otwórz
  • Klikamy OK, gratulacje obrazek dodano

Następnie dodajemy jakieś pierdoły które mają być w tym oknie (np. przyciski), następnie naciskamy F9, aby program wygenerował nam kod w stylu:



#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("MPC_tutorial", 601, 242, 192, 142)
$Pic1 = GUICtrlCreatePic("C:\Users\Ja\Desktop\gui.gif", 0, 0, 600, 241)
$Button1 = GUICtrlCreateButton("AutoIt", 144, 112, 97, 33)
$Button2 = GUICtrlCreateButton("Newsy", 256, 112, 97, 33)
$Button3 = GUICtrlCreateButton("Pogaduszki", 144, 160, 97, 33)
$Button4 = GUICtrlCreateButton("Zbanowani", 256, 160, 97, 33)
$Button5 = GUICtrlCreateButton("X", 0, 9, 17, 17)
$Button6 = GUICtrlCreateButton("+", 90, 157, 17, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
 
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
 
    EndSwitch
WEnd



Po wklepaniu tego w SciTE otrzymujemy coś takiego:
35908119.th.png

Okno ma belkę z nazwą, przyciski nie działają, a nasze tło nie zniknęło.
Oczywiście nie jest to efekt jaki chcemy osiągnąć :P
Niezbędne zmiany wprowadzimy we wszystkim znanym programie SciTE

GUI powinien używać:
$WS_POPUP - bez ramki
$WS_EX_LAYERED - przeźroczysty

$Form1 = GUICreate("MPC_tutorial", 600, 241, 192, 142,$WS_POPUP, $WS_EX_LAYERED)



Po tym zabiegu wygląda to tak:
43468171.th.png/url]


Mamy więc okno bez belki i bez naszego tła.
Oczywiście to nadal nie koniec, przez brak belki nie możemy przesunąć okna i nadal nie możemy wcisnąć przycisku żadnego.
Wracamy do naszego SciTe:

Lektura dla rządnych wiedzy znajduje się
tutaj
Natomiast pozostali powinni poznać chociaż te dwie funkcje:

Przeciąganie okna łapiąc za dowolne miejsce lewym przyciskem:
Func _GUIDrag()
Local $hGUI = @GUI_WinHandle
Local $aCurInfo = GUIGetCursorInfo($hGUI)
If $aCurInfo[4] = 0 Then ; Mouse not over a control
DllCall("user32.dll", "int", "ReleaseCapture")
_SendMessage($hGUI, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
EndIf
EndFunc ;==>_GUIDrag



Jednak po skorzystaniu z podglądu pulpitu (Win+D) wszystko się buguje i znów nie możemy oknem poruszyć dlatego nie możemy zapomnieć o:

Func _RestoreOnDesktop()
If _IsPressed('5B', $hUser32DLL) And _IsPressed(44, $hUser32DLL) Then
GUISetState(@SW_HIDE, $Form1)
GUISetState(@SW_SHOW, $Form1)
EndIf
EndFunc ;==>_RestoreOnDesktop


Natomiast problem z przyciskami rozwiążemy dodając:
GUICtrlSetState(-1, $GUI_DISABLE)


W kolejnej linii za GUICtrlCreatePic (przykład niżej w kodzie źródłowym).

Po tych wszystkich zabiegach mój efekt końcowy wygląda tak:
koniecf.png


Możecie to pobrać tutaj:

http://www48.zippyshare.com/v/15399936/file.html 

Skan:
https://www.virustotal.com/pl/file/4c71a8e6d746fe99ef78bad45a754a4f78b569e49474f30e51d95c6d614d125f/analysis/1363713185/ 

Kod źródłowy:



#NoTrayIcon
#RequireAdmin

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <WinApi.au3>

Opt('GUIOnEventMode', 1)

Global $hUser32DLL = DllOpen('user32.dll')

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("MPC_tutorial", 600, 241, 192, 142,$WS_POPUP, $WS_EX_LAYERED)
$Pic1 = GUICtrlCreatePic("C:\Users\Ja\Desktop\gui.gif", 0, 0, 600, 241)
GUICtrlSetState(-1, $GUI_DISABLE)
$Button1 = GUICtrlCreateButton("AutoIt", 144, 112, 97, 33)
$Button2 = GUICtrlCreateButton("Zbanowani", 256, 160, 97, 33)
$Button3 = GUICtrlCreateButton("Pogaduszki", 144, 160, 97, 33)
$Button4 = GUICtrlCreateButton("Newsy", 256, 112, 97, 33)
$Button5 = GUICtrlCreateButton("+", 90, 157, 17, 17)
$Button6 = GUICtrlCreateButton("X", 0, 9, 17, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit') ;
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, '_GUIDrag')

For $i = $Button1 To $Button6
GUICtrlSetOnEvent($i, '_Control_Event')
Next

AdlibRegister('_RestoreOnDesktop')

While 1
Sleep(100)
WEnd

Func _Control_Event()
Switch @GUI_CtrlId
Case $Button6
Exit
Case $Button1
ShellExecute('http://www.mpcforum.pl/forum/190-autoit/')
Case $Button2
ShellExecute('http://www.mpcforum.pl/forum/151-zbanowani/')
Case $Button3
ShellExecute('http://www.mpcforum.pl/forum/2-pogaduszki/')
Case $Button4
ShellExecute('http://www.mpcforum.pl/forum/22-newsy-z-ycia-forum/')
Case $Button5
ShellExecute('http://www.mpcforum.pl/user/856055-ibbt/')
EndSwitch
EndFunc ;==>_Control_Event

Func _GUIDrag()
Local $hGUI = @GUI_WinHandle
Local $aCurInfo = GUIGetCursorInfo($hGUI)
If $aCurInfo[4] = 0 Or $aCurInfo[4] = $Pic1 Then
DllCall("user32.dll", "int", "ReleaseCapture")
_SendMessage($hGUI, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
EndIf
EndFunc ;==>_GUIDrag

Func _RestoreOnDesktop()
If _IsPressed('5B', $hUser32DLL) And _IsPressed(44, $hUser32DLL) Then
GUISetState(@SW_HIDE, $Form1)
GUISetState(@SW_SHOW, $Form1)
EndIf
EndFunc ;==>_RestoreOnDesktop

Func _Exit()
DllClose($hUser32DLL)
Exit
EndFunc ;==>_Exit




No i na koniec trzy wskazówki:

________

#21.03 - edit

 

Dzisiaj bardzo króciutko, mamy już okno które ma kształt jaki mu nadaliśmy, co jednak jeżeli chcemy aby było przeźroczyste ?

Może najpierw pokaże kod, a później wytłumaczę:

#include <GUIConstants.au3>

Example()

Func Example()
    Local $hGUI = GUICreate("Półprzeźroczyste okno", 300, 300)
    GUISetState(@SW_SHOW, $hGUI)
    WinSetTrans($hGUI, "", 125)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete($hGUI)
EndFunc   ;==>Example

 

Tak, a więc ogólna zasada działania programu jest prosta, uruchamiamy i uzyskujemy okno 300x300 pixeli o 50% przeźroczystości. Tylko jak to działa? :)

Każdy kto chociaż trochę zna język angielski domyśla się że to dzięki "WinSetTrans" tylko dlaczego tam jest 125? i dlaczego daje to 50%?

Zapisując kolory mamy 4 grupy, każda od 0 do 255 (8 bitów - 1111 1111 na kolor) tak więc mamy 3 takie grupy kolorów zielony, czerwony i niebieski każdy zajmuje 8 bitów co daje nam 16.581.375 możliwych kolorów, dlaczego więc jest ta 4 liczba?

Jest to kanał alfa - przeźroczystość z tym, że 255 to "8 bitów widoczności", a 0 to ich brak (w uproszczeniu xD) tak więc okno gdzie ustawimy sobie:

WinSetTrans($hGUI, "", 255)

 

będzie nieprzeźroczyste, natomiast:

WinSetTrans($hGUI, "", 1)

 

Będzie niemalże niewidoczne.

 

Miłych eksperymentów :)

Opublikowano

OnEventMode - zjebałeś za przeproszeniem.

Nie wygląda to tak jak opisałeś, lecz tak:

Opt("GuiOnEventMode", 1)

$GUI = GUICreate()
$kontrolka1 = GUICtrlCreateKontrolka()
;...reszta kontrolek
GUICtrlSetOnEvent($kontrolka1, "funkcja1")
;...tak samo z resztą kontrolek, pierwszy parametr to uchwyt do niej, drugi to nazwa funkcji która wykona się po kliknięciu w nią

Func funkcja1()
;kod który się wykona po kliknięciu w kontrolka1
EndFunc

While 1 ;petla trzymająca program przy życiu
Sleep(100)
WEnd
846331404756772371599.jpeg
Opublikowano

To uproszczona forma (wygląda mniej-więcej tak a nie "dokładnie tak"), ktoś kto chce sobie zmienić kształt okna nie musi znać zaawansowanej wersji w stylu:

#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode 
$mainwindow = GUICreate("Hello World", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("Hello world! How are you?", 30, 10)
$okbutton = GUICtrlCreateButton("OK", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")

$dummywindow = GUICreate("Dummy window for testing ", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")

GUISwitch($mainwindow)
GUISetState(@SW_SHOW)

While 1
  Sleep(1000)  ; Idle around
WEnd

Func OKButton()
  ;Note: at this point @GUI_CTRLID would equal $okbutton
  MsgBox(0, "GUI Event", "You pressed OK!")
EndFunc

Func CLOSEClicked()
  ;Note: at this point @GUI_CTRLID would equal $GUI_EVENT_CLOSE,
  ;@GUI_WINHANDLE will be either $mainwindow or $dummywindow
  If @GUI_WINHANDLE = $mainwindow Then 
    MsgBox(0, "GUI Event", "You clicked CLOSE in the main window! Exiting...")
    Exit
  EndIf 
EndFunc 

Bo to jest w linku powyżej. Niezbędne natomiast było zaznaczenie różnicy i to zrobiłem :P

Nie mniej jak będzie to bolało więcej osób zamienię formę przybliżoną na dokładną jak powyżej :P

 

by the way, twój kod nie jest do końca poprawny gdyż pętelkę trzymajacą program przy życiu dajemy przed funkcjami w wyniku czego mamy niemalże identyczny kodzik.

Przyznam jednak, że zapomniałem dodać na początku:

Opt("GuiOnEventMode", 1)

I już poprawiam :P

Opublikowano

Ciekawe od kiedy pętelkę trzymamy przed funkcjami.. jeśli chcemy żeby nam bugowało?

Nie bez powodu mam takie ułożenie kodu. Kiedyś pisałem programik który wyświetlał status działania w labelach. Kiedy funkcje były za pętlą to GUICtrlSetData (nie wiedzieć czemu) nie działało. Po przełożeniu pętli na sam koniec wszystko śmiga.

Dzieje się tak dlatego, że AutoIT piekielnie się buguje z niewiadomych powodów. Dlatego zawsze lepiej się zabezpieczyć.

 

Zmniejsz sleepa do 100, przy 1000 będą straszne lagi.

 

I dla przejrzystości kodu trzymaj SetOnEvent pod stworzeniem wszystkich kontrolek - ładniej i przejrzyściej to wszystko wygląda.

846331404756772371599.jpeg
Opublikowano

Ciekawe od kiedy pętelkę trzymamy przed funkcjami.. jeśli chcemy żeby nam bugowało?

Nie bez powodu mam takie ułożenie kodu. Kiedyś pisałem programik który wyświetlał status działania w labelach. Kiedy funkcje były za pętlą to GUICtrlSetData (nie wiedzieć czemu) nie działało. Po przełożeniu pętli na sam koniec wszystko śmiga.

Dzieje się tak dlatego, że AutoIT piekielnie się buguje z niewiadomych powodów. Dlatego zawsze lepiej się zabezpieczyć.

Wszędzie gdzie nie znajdę czegoś na ten temat pętelka trzymająca program przy życiu jest przed funkcjami, nie spotkałem się z bugowaniem. Oczywiście chętnie bym zobaczył jakiś przykładowy kod gdzie jest użyte GUIOnEvent się coś sypie przez to że pentelka jest wcześniej.

Jutro sprawdzę jak to się ma przy większej ilości możliwych opcji do wyboru i większej liczbie funkcji, jeżeli będzie się sypało poprawię to, ale raczej mało prawdopodobne ;)

Opublikowano

Również sprawdziłem kilka kodów i nie było problemów, tak wiec zostaje jak jest :P

  • 4 tygodnie później...
Opublikowano

nie działa mi przezroczystość okna z przezroczystym tłem. nie wiem czemu.

 

$hGui = GUICreate("", 751, 521, 460, 452, $WS_POPUP, $WS_EX_LAYERED)
$Pic1 = GUICtrlCreatePic("C:\Users\Mistrzu\Desktop\pic.bmp", 0, 0, 750, 520)


While 1
	$trans=GUICtrlRead($Slider1)
	WinSetTrans($hGui,"",$trans*2)
	sleep(100)
WEnd

 

 

próbowałem nawet dodać przed sleepem

	GUISetStyle($WS_POPUP, $WS_EX_LAYERED,$hGui)

 

ale wtedy strasznie miga

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...