Skocz do zawartości

Burn

Członkowie
  • Postów

    0
  • Dołączył

  • Ostatnio

    Nigdy

Wszystko napisane przez Burn

  1. Witam Najprosciej używajac funkcji ShellExecute :) Można też uzyć CreateProcess w zależnosć co chcesz z danym programem (który chcesz uruchomić) zrobć. Jeżeli chcesz tylko go uruchomić to ShellExecute w zupełności wystarczy. Pozdrawiam
  2. Witam Jeżeli główne okno ma odpowiadającą Ci czcionkę to najprosćiej jest probrać za pomocą komunikatu WM_GETFONT uchwyt czcionki głownego okna i wysłać komunikat WM_SETFONT do Twojej kontrolki Tab. Jeżeli chcesz stworzyć własna czcionkę to służą do tego funkcje: CreateFont i CreateFontIndirect do usunięcia czcionki (gdy już nie będzie potrzebna) użyj DeleteObject Pozdro
  3. Niestety w kontrolce Tab poszczególne zakładki nie posiadają uchwytów :( Tak jak tutaj napisał kiedyś Nicon, trzeba na piechotę bawić się funkcją ShowWindow.
  4. Witam Jak tworzyłeś kontrolkę Tab Jeżeli robileś to za pomocą CreateWindow (ew. CreateWindowEx) to te funkcje właśnie zwracają uchwyt kontrolki którą tworzysz. :) Jeżeli natomiast zrobiłeś kontrolkę Tab w zasobach to do pobrania jej uchwytu możesz użyć funkcji GetDlgItem . Pozdro
  5. Burn

    Ping

    Dzięki, już sobie poradziłem :) Wszystko działa :) Napisałem (w MASM) to tak: To jest kod modułu ping.inc include wsock32.inc includelib wsock32.lib PingInit PROTO PingClean PROTO Ping PROTO :DWORD,:DWORD,:DWORD,:WORD .const ECHO_PACKET_SIZE equ 32 ;rozmiar pakietu danych PING_INIT_OK equ 0 PING_INIT_ERROR_LOADLIB equ 1 PING_INIT_ERROR_GETPROCADDR equ 2 PING_INIT_ERROR_WSASTARTUP equ 3 PING_INVALID_HOSTNAME equ -1 .data szIcmp db "icmp.dll",0 szIcmpCreateFile db "IcmpCreateFile",0 szIcmpCloseHandle db "IcmpCloseHandle",0 szIcmpSendEcho db "IcmpSendEcho",0 .data? hIcmp dd ? lpIcmpCreateFile dd ? lpIcmpCloseHandle dd ? lpIcmpSendEcho dd ? .code PingInit proc LOCAL wsa: WSADATA invoke LoadLibrary, offset szIcmp cmp eax, 0 je errorloadlib mov hIcmp, eax invoke GetProcAddress, hIcmp, offset szIcmpCreateFile cmp eax, 0 je errorgetprocaddr mov lpIcmpCreateFile, eax invoke GetProcAddress, hIcmp, offset szIcmpCloseHandle cmp eax, 0 je errorgetprocaddr mov lpIcmpCloseHandle, eax invoke GetProcAddress, hIcmp, offset szIcmpSendEcho cmp eax, 0 je errorgetprocaddr mov lpIcmpSendEcho, eax invoke WSAStartup, 0101h, addr wsa cmp eax, 0 jne errorwsastartup sub eax, eax ret errorwsastartup: inc eax ;eax = 3 Error PING_INIT_ERROR_WSASTARTUP errorgetprocaddr: push eax invoke FreeLibrary, hIcmp pop eax inc eax ;eax = 2 Error PING_INIT_ERROR_GETPROCADDR errorloadlib: inc eax ;eax = 1 Error PING_INIT_ERROR_LOADLIB ret PingInit endp PingClean proc invoke WSACleanup invoke FreeLibrary, hIcmp ret PingClean endp Ping proc uses esi lpAddr:DWORD, lpEcho:DWORD, lpOptions:DWORD, TimeOut:WORD LOCAL addrIP: DWORD LOCAL hIcmpFile: DWORD LOCAL acPingBuffer[ECHO_PACKET_SIZE]: BYTE invoke inet_addr, lpAddr mov addrIP, eax .if eax == INADDR_NONE invoke gethostbyname, lpAddr .if eax == 0 dec eax ;eax = -1 PING_INVALID_HOSTNAME ret .endif mov eax, dword ptr [eax + 12] mov eax, dword ptr [eax] mov eax, dword ptr [eax] mov addrIP, eax .endif invoke RtlFillMemory, addr acPingBuffer, ECHO_PACKET_SIZE, 0AAh call lpIcmpCreateFile mov hIcmpFile, eax mov esi, lpEcho assume esi: ptr ICMP_ECHO_REPLY lea eax, acPingBuffer mov [esi].DataPointer, eax mov [esi].DataSize, ECHO_PACKET_SIZE assume esi: nothing push TimeOut push sizeof ICMP_ECHO_REPLY + ECHO_PACKET_SIZE push lpEcho push lpOptions push ECHO_PACKET_SIZE lea eax, acPingBuffer push eax push addrIP push hIcmpFile call lpIcmpSendEcho push eax push hIcmpFile call lpIcmpCloseHandle pop eax ret Ping endp Najpierw wywołuję funkcję PingInit, później Ping i odpowiednio formatuję dane które podaję/otrzymuję no i po wszystkim PingClean. Parametry funkcji Ping to: lpAddr - adres lub nazwa hosta lpEcho - adres zmiennej typu ICMP_ECHO_REPLY (zwraca potrzebne mi informacje) lpOptions - adres zmiennej typu ICMP_OPTIONS (tu podaję niektóre dane np. TTL) TimeOut - max. czas odpowiedzi Wydaje mi się że wszystko działa poprawnie, gdyby jednak ktos zauważył jakiś błąd to proszę o wyjaśnienie co i dlaczego jest źle. Pozdrawiam
  6. Burn

    Ping

    Witam Może i to dość proste, jednak ja nigdy nie zajmowalem sie programowaniem aplikacji sieciowych przy użyciu WinApi. Czy ktoś może podać przykład jak napisać (oczywiście w WinApi) funkcję która zwróci te informacjie co komenda Ping (W takiej lub podobnej postaci) z tym, że chcę mieć dostęp do poszczególnych zawartych tam informacji. Dobrze by było gdyby można podać nazwę lub adres IP. Pozdro
  7. Burn

    odswiezanie okna

    Witam Okno (a nawet jego określony obszar) możesz odrysować za pomocą funkcji InvalidateRect (ewentualnie InvalidateRgn) którą byś musiał wywołać po każdej operacji po której okno wymagałoby odświezenia. Zastanawiam sie nad tym w jaki sposób wyświetlasz bitmapy, ale chyba na w obsłudze komunikatu WM_PAINT. Radzę wszyskie operacje rysowania, wyświetlania bitmap wykonywać właśnie w po wywołaniu przez system tego komunikatu (WM_PAINT), wtedy pobierasz za pomocą BeginPaint uchwyt device context okna ktore wymaga odrysowania następnie malujesz po oknie (wyświetlasz bitmapy) i po tym wszystkim wywołujwsz EndPaint. Pozdro
  8. Witam Nie bardzo wiem o co chodzi Czu chodzi tylko o odczytanie wersji programu czy faktycznie o wydobycie z pliku zasobów typu RT_VERSION . Jeżeli chcesz tylko uzyskać informacje o wersji trzeba użuć funkcji GetFileVersionInfo przykład jest tutaj:) Pozdro
  9. Witam Czy nie chodzi Ci przypadkiem o PropertySheet czyli Dialog na którym znajduje się SysTabControl32( na którego zakładkach możesz wyświetlać okna dialogowe) i posiadający Buttony OK, Anuluj, Zastosuj . Czyli po prostu taki dialog na który dobrze nadaje się jako okno ustawień programu Jeżeli tak to proponuję poszukać w google właśnie pod hasłem PropertySheet Jeżeli nie znajdziesz nic ciekawego to napisz jak będę miał czas to napisze jutro (dzisiaj nie mam czasu) przykład (tylko pewnie w MASM) :) Pozdro
  10. Burn

    Problem z ecvt

    Witam Kod w porządku :) W kontrolce EDIT powinno pojawić się 3298 (tak jak napisałem bez separatora dziesiętnego). Jeżeli kontrolka EDIT nie wyświetla tekstu to winne za to mogą być nieprawidłowy uchwyt hKalk lub nieprawidłowy ID kontrolki 502. Pomijam już to, że z niewiadomych przyczyn używasz EM_REPLACESEL do wyświetlenia tekstu w EDIT zamiast WM_SETTEXT lub SetWindowText. Chyba, że rzeczywiście chcesz zmieniać zaznaczony tekst. W każdym razie podany kod powinien dzialać chyb, że popełniłeś jeden ze wspomnianych błedów (ew. oba na raz). Pozdro
  11. Burn

    uchwyt do procesu

    Witam O jakie procesy chodzi Może o usługi systemów NT , jeżeli tak to nie wiem dokładnie bo mam Win 98 ale chyba trzeba by coś pokombinować z funkcjami OpenSCManager, OpenService, SetServiceStatus ale nic więcej na ten temat nie wiem bo nie mam na czym z tym poeksperymentować. Pozdro
  12. Burn

    uchwyt do procesu

    Nie no nie zalamuj się. To mój pierwszy program w C++ ale wcześniej z WinApi korzystałem w Delphi i MASM. Co do ksiązek o WinApi to najbardziej znana jest Charles Petzold "Programowanie Windows" niestety dotyczy ona tylko GUI. Nie znam niestety polskiej ksiązki w której były by opisane funkcje dotyczące procesów.
  13. Witam Nie na pisałeś z czym już kombinowałeś i jak tworzysz ten BUTTON. Nie sprawdziłem ale może spróbuj CreateWindowEx a w pierwszym parametrze podając WS_EX_TRANSPARENT (reszta parametrów jak CreateWindow). Nie wiem też co chcesz uzyskać czy chodzi o zwykłą zmianę koloru tła czy on musi być koniecznie przezroczysty np. po to aby nie przykrywał obrazka tła. Pozdro
  14. Burn

    Windows Longhorn

    Witam Nie wydaje mi się, aby były to jakieś drastyczne zmiany. Co najwyżej dojdą nowe funkcje, a to przecież pozytywna zmiana :) Wydaje mi się, że M$ nie może wprowadzić zbyt dużych zmian, ponieważ na tym systemie muszą (a przynajmniej powinny) się też uruchamiać programy napisane pod starsze systemy (kompatybilność wstecz). Więc wydaje mi się, że nie ma powodów do obaw. Pozdro
  15. Burn

    uchwyt do procesu

    Witam Napisałem przykład :D To mój pierwszy program w C++ wiec proszę się nie śmiać jak coś namieszałem :P Jest to program, który zamyka Gadu-Gadu (Tlena nie mam). Program był kompilowany pod Dev-C++ 4.9.9.0 i sprawdzony na Win 98 ale wydaje mi się że powinien też działać na Win XP. :) #include <windows.h> #include <tlhelp32.h> int main(void) { HANDLE hSnapshot = NULL; //Uzyskaj uchwyt migawki systemu hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 ProcInfo; //W tej zmiennej bedziemy otrzymywać info o procesach ZeroMemory(&ProcInfo, sizeof(ProcInfo)); //Wyczyść strukturę PROCESSENTRY32 ProcInfo.dwSize = sizeof(ProcInfo); //Zapisz jej rozmiar Process32First(hSnapshot, &ProcInfo); //Pierwszy Proces DWORD GGProcID = 0; //Nowa zmienna do przzechowywania ID Procesu do { //Szukamy Gadu-Gadu. Zwróć uwagę na podwójny "\" w ścieżce if (lstrcmpi(ProcInfo.szExeFile, "C:\\Program Files\\Gadu-Gadu\\GG.EXE") == 0) { GGProcID = ProcInfo.th32ProcessID; //Zapisz ID Procesu break; //Przerwij - po co dalej szukać jak już znaleźliśmy :) } } while (Process32Next(hSnapshot, &ProcInfo)); //Następny uruchomiony proces CloseHandle(hSnapshot); //Zamklnij uchwyt if (!GGProcID) { //Czy ID Procesu to 0 //Wyświetl komunikat MessageBox(0, "Nie znaleziono Gadu-Gadu", NULL, MB_ICONERROR); return 0; //Zwróć 0 } HANDLE hGGProc = NULL; //Uchwyt procesu //Trzeba otworzyć proces z proces aby uzyskać prawa do jego zakończenia if (!(hGGProc = OpenProcess(PROCESS_TERMINATE, FALSE, GGProcID))) { //Wyświetl komunikat MessageBox(0, "Błąd OpenProcess. Nie udało się uzyskać praw do zamknięcia.", NULL, MB_ICONERROR); return 0;//Zwróć 0 } TerminateProcess(hGGProc, 0); //Zakończ proces CloseHandle(hGGProc); //Zamknij uchwyt //Zwróć 1 return 1; } W przykładzie dla uproszczenia założyłem, że CreateToolhelp32Snapshot nie zwróci błedu i Process32First też się powiedzie (najprawdopodobniej w systemie jest uruchomiony conajmniej 1 proces). Ale jeżeli wykorzystujesz go w "normalnym" programie to oczywiście musisz liczyć się z możliwością wystąpienia błedu. Mam nadzieję, że Ci pomoże. Gdyby coś jeszcze było niejasne to pytaj. Pozdro
  16. Burn

    uchwyt do procesu

    Witam Jeżeli nie chodzi Ci tylko o zdobycie uchwytu procesu to nie wiem dobrze jak jej użyć bo ciągle używam Win 98 ale w miarę łatwo możesz to zrobić za pomocą CreateToolhelp32Snapshot i Process32First, Process32Next możesz też przeczytać https://www.winapi.org/index.php?option=content&task=view&id=88&Itemid=33 jeżeli sobie nie poradzisz to napisz napiszę przykład (w tej chwili jestem zajęty) Pozdro
  17. Witam Niestety nie znam metody by robić to automatycznie (za pomocą styli) :( ale można sobie napisać funkcję, która posortuje elementy listy.   Po dodaniu każdego (oczywiście jeżeli dodajemy jednoczesnie dużą liczbę elementów to robimy to tylko po dodaniu wszystkich) elementu do listy trzeba wywołać: ;jeżeli wParam = 0 sortowanie rosnące, 1 malejące ;lParam to adres funkcji sortującej invoke SendMessage,hLView, LVM_SORTITEMS, 0, addr LVSortProc Funkcja sortująca może być np. taka: LVSortProc proc lParam1: LPARAM, lParam2: LPARAM, lParamSort: LPARAM LOCAL szBuff1[256]:BYTE LOCAL szBuff2[256]:BYTE LOCAL lvi:LV_ITEM ;Wypełnij struktrę LV_ITEM mov lvi.imask, LVIF_TEXT mov lvi.cchTextMax, 256 mov lvi.iSubItem, 0 lea eax, szBuff1 mov lvi.pszText, eax ;Pobierz teksty do porownania invoke SendMessage, hLView, LVM_GETITEMTEXT, lParam1, addr lvi lea eax, szBuff2 mov lvi.pszText, eax invoke SendMessage, hLView, LVM_GETITEMTEXT, lParam2, addr lvi ;Porwnaj teksty (ignorując wielkość liter) invoke lstrcmpi, addr szBuff1, addr szBuff2 .if lParamSort == 1 ;Jeżeli chcemy sortować malejąco neg eax ;trzeba zmienić znak wyniku porwnania na przeciwny .endif ret LVSortProc endp Oczywiście funkcja w tej postaci zawsze sortuje elementy wg. tekstu Item (pierwszej kolumny) ale można ją przerobić tak, aby sortowała wg. dowolnego SubItem (dowolnej kolumny). Myślę, że jeżeli będziesz miał potrzebę sortowania według kolumn to z tym już sobie poradzisz, ale jeżeli jednak nie to napisz. Pozdro
  18. Witam Cieszę się, że się przydało :D Niestety nie wiem, dlaczego źle interpretuje akurat to. Zrobiłem nawet sobie z ciekawości przykładową funkcję gdzie parametrami były kolejno 2 byte, 2 word, 2 dword i wszystko Ok (na stos rzeczywiście jest wrzucony dword przynajmniej tak pokazuje dissasembler). Być może wina leży w tym, że wsprintf ma nie określoną liczbę argumentów. Pozdro
  19. Witam 1. No właśnie chodziło mi o to, że flaga LVFI_NEARESTXY dziala tylko przy stylach LVS_SMALLICON i LVS_ICON. Więc dlatego zwraca Ci -1. Aby szukać pozycji najbliższej kursora musisz napisać własną procedurę jednak ja tego nigdy nie robiłem (nie miałem potrzeby) więc Ci nie podpowiem jak. Natomiast jeżeli chcesz znaleźć tylko pozycję zawierającą określony ciąg znaków (string) to jest proste trzeba tylko ustawić pola struktury LV_FINDINFO .flags na LVFI_STRING lub LVFI_PARTIAL i .psz na adres szukanego ciagu znaków (przy LVFI_STRING musisz podać cały natomiast przy LVFI_PARTIAL wystarszy tylko początek) Póżniej wystarczy tylko wywołać: ktory=ListView_FindItem(hListView,-1, &znajdz); 2. Kiedyś w MASM na swoje potrzeby napisałem taką funkcję. Jeżeli nie bedziesz umiał tego przetłumaczyć na C++ to gdzieś poczytaj o LVM_GETITEM Parametry: hListView: HWND - uchwyt ListView iItemNo: DWORD - Numer Item (czyli wiersza) iSubItemNo: DWORD - Numer SubItem (czyli kolumny) lpText: LPSTR - Adres buforka w którym będzie zwrócony tekst MaxLen: DWORD - Maksymalna długość zwracenego tekstu (naie więcej niż długosć bufora) Uwaga: Wiersze i kolumny numerowane są od 0 GetListViewText proc hListView: HWND, iItemNo: DWORD, iSubItemNo: DWORD, lpText: LPSTR, MaxLen: DWORD LOCAL lvi:LV_ITEM push iItemNo pop lvi.iItem push iSubItemNo pop lvi.iSubItem mov lvi.imask, LVIF_TEXT push lpText pop lvi.pszText push MaxLen pop lvi.cchTextMax invoke SendMessage, hListView, LVM_GETITEM, 0, addr lvi ret GetListViewText endp 3. Niestety tu jest problem ponieważ wywołanie Dialogu za pomocą DialogBoxParam lub makra DialogBox tworzy modalne okno dialogowe, co uniemożliwia wywołnie drugiego dialogu spróbuj użyć CreateDialogParam albo makra CreateDialog (parametry bez zmian). Powinno działać :P 4. Składnia: CONTROL text, id, class, style, x, y, width, height [, extended-style] text - tekst kontrolki id - identyfikator class - klasa x, y - pozycja kontrolki względem głownego okna width - szerokość height - wysokość extended-style - styl rozszerzony (parametr opcjonalny) Jak z tego wynika pole text pozostawiasz bez zmian (przecież kontrolka nie ma wyświetlać tekstu tylko bitmapę). Aby wyświetlić bitmapę trzeba za pomocą funkcji LoadBitmap załadowąc bitmapę z zasobów a następnie trzeba wysłać komunikat STM_SETIMAGE do kontrolki którego wParam to IMAGE_BITMAP (chcemy załadować bitmapę) a lParam to uchwyt bitmapy. W MASM można to zrobić tak: invoke LoadBitmap, hInstance, ID_BITMAPY invoke SendDlgItemMessage, hWnd, ID_KONTROLKI, STM_SETIMAGE, IMAGE_BITMAP, eax Ale się rozpisałem :) Mam nadzieję, że przynajmniej trochę pomogłem. Uwaga Post został zmodyfikowany (dokładnie 3 punkt) bo tam wcześniej napisałem takie bzdury, że wstyd się przyznawać... Pozdro
  20. Witam Coś na ten temat jest w MSDN Pozdro
  21. Witam Problem nie tkwi w samej funkcji wsprintf a w sposobie przekazywania parametrów. Kompilator spodziewa się argumentu 32 bitowego (dword) a otrzymuje 16 bitowy (word). Dlatego uzupełnia to sobie w niezbyt mądry sposób przez dodanie push 0 pomiędzy argumentami. Aby pozbyć się prolemu można napisać tak: sub eax, eax ;lepiej wyzerować rejestr mov ax, STime.wYear ;zapisz word do rejeestru ax push eax ;teraz idzie dword na stos jak oczekuje kompilator mov ax, STime.wMonth push eax mov ax, STime.wDay push eax mov ax, STime.wMinute push eax mov ax, STime.wHour push eax lea eax, templateData push eax lea eax, fsBuf push eax call wsprintf Myślę ,że to lepsze od Twojego obejścia problemu a taksamo działa :P Pozdro
  22. Witam 1. Czy napewno chcesz szukać item najbliższy od aktulnej pozycji kursora tak Jeżeli tak to jak styl ma Twój ListView bo w MSDN piszą, że flaga LVFI_NEARESTXY działa tylko przy durzych i małych ikonach. 2. Nazwy z sąsiednich kolumn Chodzi o nagłówki listy, czy o zawartość sąsiednich kolumn listy (SubItem) 3. Jak wywołujesz drugi dialog Jeżeli np. po naciśnięciu na przycisk to powinno działać w ten sposób, że każdy dialog ma osobną procedurę z tym ,że w wywołaniu idrogiego dialogu za pomocą DialogBoxParam musisz ustawić trzeci parametr hWndParent (uchwyt rodzica) na uchwyt dialogu pierwszego. 4. O co chodzi z tą Bitmapą Chcesz wyświetlić bitmapę na dialogu? Można by to zrobić w obsłudze komunikatu WM_PAINT ale to jest bardziej skomplikowane znacznie prościej jest utworzenie na dialogu kontrolki Static ze stylem SS_BITMAP i jeżeli bitmapa znajduje sie w zasobach to załadować ją za pomocą LoadBitmap, natomiast jeżeli bitmapa znajduje się w pliku to trzeba użyć LoadImage. To wszystko co mogę teraz napisać, napisz bardziej szczegółowo pytania na, które nie dostałeś satysfakcionującej odpowiedzi. Pozdro
  23. Burn

    Menu kontekstowe

    Witam Zobacz na to: Use Shell ContextMenu in your applications Pozdro
  24. Burn

    funkcja cofnij

    Witam Jeżeli piszesz program graficzny to wydaje mi się, że chwili gdy użytkownik zacznie używać jakiegoś narzędzia musisz zapisać do bufora aktualny obraz. Jeżeli chcesz mieć możliwość cofania np. 10 razy to musisz utworzyć sobie 10 elementową tablicę buforków i w chwili operacji odpowiednio zmieniać miejscami elementy tablicy i nadpisywać ostatni buffor w tablicy. Pozdro
  25. Burn

    okna dialogowe

    Witam Napałem przykład niestety w MASM (ale uprzedzałem) mam nadzieję, że to będzie zrozumiałe. Procedura, którą za pomocą subclassingu zastąpimy standardową procedurę obsługi Dialogu. Musimy korzystać z subclassingu tylko wtedy gdy umieszczamy własne kontrolki na oknie dialogowym i chcemy otrzymywać od nich komunikaty. Jeżeli jednak nie umieszczmy dodatkowych kontrolek to na obsługę już istniejących wystarsza sama procedura OFNHookProc trzeba tylko obsłużyć odpowiednie komunikaty. NewDialogProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if uMsg==WM_COMMAND mov eax, lParam .if eax == hNowy ;Kliknięto nasz przycisk .endif .endif ;Przywołaj orginalną procedurae obsługi okna dialogowego invoke CallWindowProc, lpOldDialogProc,hWnd,uMsg,wParam,lParam ret NewDialogProc endp Procedura obługi dialogu dla Hooka. W przykładzie za pomocą obsługi komunikatu WM_NOTIFY wyświetli MassageBox po zmianie filtra plików. Przy obsłudze WM_INITDIALOG zmieniamy jego rozmiar okna dialogowego, tworzymy dodatkowy przycisk na oknie dialogowym, zmieniamy jego czcionkę. Za pomocą SetWindowLong zmieniamy też procedurę obsługi okna dialogowego (bez tego niemoglibyśmy obsługiwać komunikatów dodatkowego przycisku) OFNHookProc proc uses esi hDlg:HWND, uiMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hDialog: DWORD LOCAL hCtrl: DWORD LOCAL buf[100]:BYTE LOCAL rect: RECT .if uiMsg == WM_INITDIALOG ;PrintText "WM_INITDIALOG" invoke GetParent, hDlg ;Pobierz uchwyt dialogu mov hDialog, eax invoke GetClientRect,hDialog, addr rect ;Pobierz rozmiar okna add rect.right, 100 ;Ziększ szerokość bo musi się zmieścić przycisk ktory dodamy invoke SetWindowPos, hDialog, HWND_TOP, 0, 0, rect.right, rect.bottom,SWP_SHOWWINDOW or SWP_NOMOVE sub rect.right, 95 ;Obliczamy pozycję ;Tworzymy dodatkowy przycisk invoke CreateWindowEx, 0, offset szButton, offset szNowy, WS_CHILD or WS_VISIBLE, rect.right, 40, 80, 20, hDialog, 0, hInstance, 0 mov hNowy, eax ;Musimy jeszcze zmienić czcionkę przycisku na takąsamą jak dialogu invoke SendMessage, hDialog, WM_GETFONT, 0, 0 invoke SendMessage, hNowy, WM_SETFONT, eax, TRUE ;Zmieniamy procedurę Dialogu aby obsługiwać wszystkie komunikaty ;jakie nam się spodobają invoke SetWindowLong, hDialog, GWL_WNDPROC, addr NewDialogProc mov lpOldDialogProc, eax ;Trzeba zapamiętać adres starej procedury .elseif uiMsg == WM_NOTIFY mov esi, lParam assume esi: ptr NMHDR .if ([esi].code == CDN_SELCHANGE) ;czy zmiana filtra invoke GetParent, hDlg ;Pobierz uchwyt dialogu mov hDialog, eax invoke GetDlgItem, hDialog, TYPE_FILTERS_COMBO_FIELD ;Identyfikator ComboBox = 0470h mov hCtrl, eax invoke SendMessage, eax, CB_GETCURSEL, 0, 0 ;Pobierz index mov edx, eax invoke SendMessage, hCtrl, CB_GETLBTEXT, edx, addr buf ;Pobierz tekst invoke MessageBox, 0, addr buf, addr szAppName, MB_OK ;Wyświetl komunikat .endif assume esi: nothing .endif ret OFNHookProc endp No i procedura obsługi okna naszej aplikacji WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_CREATE ;Wypełnij strukturę OPENFILENAME mov ofn.lStructSize, sizeof OPENFILENAME mov eax, hWnd mov ofn.hWndOwner, eax mov ofn.hInstance, 0 mov ofn.lpstrFilter, offset szFilter mov ofn.lpstrCustomFilter, 0 mov ofn.nMaxCustFilter, 0 mov ofn.nFilterIndex, 0 mov ofn.lpstrFile, 0 mov ofn.nMaxFile, MAX_PATH mov ofn.lpstrFileTitle, 0 mov ofn.nMaxFileTitle, MAX_PATH mov ofn.lpstrInitialDir, 0 mov ofn.lpstrTitle, 0 ;Ważne jest: OFN_EXPLORER or OFN_ENABLEHOOK mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_EXPLORER or OFN_ENABLEHOOK mov ofn.nFileOffset, 0 mov ofn.nFileExtension, 0 mov ofn.lpstrDefExt, 0 mov ofn.lCustData, 0 mov ofn.lpfnHook, offset OFNHookProc ;Tu adres nowej procedurki obsługi dialogu mov ofn.lpTemplateName, 0 ;Utowrz przycisk po kliknięciu ktorego wywołamy OpenDialog invoke CreateWindowEx, 0, offset szButton, offset szOpen, WS_CHILD or WS_VISIBLE, 10, 10, 80, 20, hWnd, 0, hInstance, 0 mov hBtnOpen, eax .ELSEIF uMsg==WM_COMMAND mov eax, lParam .if eax == hBtnOpen ;Wywołaj Dialog invoke GetOpenFileName, addr ofn .endif .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp No tyle myślę, że przytaczanie reszty kodu jest zbędne i bez tego ten post jest wystarczajaco długi :) Gdyby jeszcze coś było niejasne to pytaj. Pozdro
×
×
  • Utwórz nowe...