Listbox i edycja pola w asemblerze

0

Witam mam za zadanie napisać program, w którym po kliknięciu na element znajdujący się w listboxie kopiuje tekst – (zawartość obiektu) w pole okna ,czyli go wyświetla.Robiłem już to dla combobox'a i działa lecz dla listy nie. Dodam,że piszę w masm32.
Oto kod:

 .586P
.MODEL flat, STDCALL
;--- pliki ---------
include .\include\grafika.inc
;--- biblioteki ---------
includelib .\lib\user32.lib
includelib .\lib\kernel32.lib
includelib .\lib\gdi32.lib
;--- stałe ---
CSstyle EQU CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
BSstyle EQU BS_PUSHBUTTON+WS_VISIBLE+WS_CHILD+WS_TABSTOP
WNDstyle EQU WS_CLIPCHILDREN+WS_OVERLAPPEDWINDOW+WS_HSCROLL+WS_VSCROLL
EDTstyle EQU WS_VISIBLE+WS_CHILD+WS_TABSTOP+WS_BORDER
CBstyle EQU WS_VISIBLE+WS_CHILD+WS_TABSTOP+WS_BORDER+CBS_DROPDOWNLIST+CBS_HASSTRINGS
LBstyle EQU WS_VISIBLE+WS_CHILD+WS_TABSTOP+WS_BORDER+CBS_HASSTRINGS
STATstyle EQU WS_VISIBLE+WS_CHILD+WS_BORDER+SS_LEFT
kolor EQU 000000FFh ; czerwony  ; kolory: G B R
;--- sekcja danych ------
_DATA SEGMENT
 hwnd        DD    0
 hinst    DD    0
 hdc        DD    0
 hbutt    DD    0
 hedt     DD    0
 hbrush     DD    0
 holdbrush  DD    0
 hcb         DD    0
 hlb         DD    0
 hmdi     DD    0
 hstat     DD    0
 ;---
 msg MSGSTRUCT <?> 
 wndc WNDCLASS <?>
 ;---
 naglow    DB    "Autor Maciej Gryczka.",0
 rozmN    DD    $ - naglow    ;ilość znaków w tablicy
 ALIGN    4    ; przesuniecie do adresu podzielnego na 4
 puste    DB    "_____________________"    ; spacje
 rozmP    DD    $ - puste    ;ilość znaków w tablicy
 ALIGN    4    ; przesuniecie do adresu podzielnego na 4
 tytul    DB "Aplikacja graficzna",0
 ALIGN 4
 cname    DB "MainClass", 0
 ALIGN 4
 MES1       DB "Lewy, myszy",0
 ALIGN 4
 tbutt    DB    "BUTTON", 0
 ALIGN 4
 tstart    DB    "Start", 0
 ALIGN 4
 tedt          DB    "EDIT", 0
 ALIGN 4
 tnazwaedt    DB    " ", 0
 ALIGN 4
 tcb          DB    "COMBOBOX", 0
 ALIGN 4
 tnazwacb    DB    " ", 0
 ALIGN 4
 tlb          DB    "LISTBOX", 0
 ALIGN 4
 tnazwalb    DB    " ", 0
 ALIGN 4
 tstat          DB    "STATIC", 0
 ALIGN 4
 tnazwastat    DB    "Test STATIC", 0
 ALIGN 4
 ttekst    DB    "tekst", 0
 ALIGN 4
 ttekst1    DB    "tekst1", 0
 ALIGN 4
 ttekst2    DB    "tekst2", 0
 ALIGN 4
 nagl        DB    "Komunikat", 0
 ALIGN 4
 terr        DB    "Błąd!", 0
 ALIGN 4
 terr2    DB    "Błąd 2!", 0
 ALIGN 4
 bufor    DB    128 dup(' ')    ; bufor ze spacjami
 rbuf        DD    128    ; rozmiar buforu
 znaczn     DD    0
 rt   RECT  <220,50,320,90>
 rr   DD    2
_DATA ENDS
;--- sekcja kodu ---------
_TEXT SEGMENT
;;;;;;;;;;;;;;;;;;;;;;;
WndProc PROC
;--- procedura okna ---
; DWORD PTR [EBP+14h] - parametr LPARAM komunikatu
; DWORD PTR [EBP+10h] - parametr WPARAM komunikatu
; DWORD PTR [EBP+0Ch] - ID = identyfikator komunikatu
; DWORD PTR [EBP+08h] - HWND = deskryptor okna
 ;------------------------------------
 push    EBP    ; standardowy prolog
 mov    EBP, ESP    ; standardowy prolog
;--- odkładanie na stos
 push    EBX
 push    ESI
 push    EDI
 cmp    DWORD PTR [EBP+0Ch], WM_CREATE
 jne    @F
 jmp    wmCREATE
@@:    
 cmp    DWORD PTR [EBP+0Ch], WM_DESTROY
 jne    @F
 jmp    wmDESTROY
@@:    
 cmp DWORD PTR [EBP+0CH], WM_COMMAND
 jne    @F
 jmp    wmCOMMAND
@@:    
 cmp DWORD PTR [EBP+0CH], WM_LBUTTONDOWN
 jne    @F
 jmp    wmLBUTTON
@@:    
 cmp DWORD PTR [EBP+0CH], WM_RBUTTONDOWN
 jne    @F
 jmp    wmRBUTTON
 
@@:    
;--- komunikaty nieobsługiwane ---
 INVOKE DefWindowProcA, DWORD PTR [EBP+08h], DWORD PTR [EBP+0Ch], DWORD PTR [EBP+10h], DWORD PTR [EBP+14h]
 jmp    konWNDPROC
wmCREATE:
;--- utworzenie okna LISTBOX ---
 INVOKE CreateWindowExA, 0, OFFSET tlb, OFFSET tnazwalb,  LBstyle, 220, 150, 100, 100, DWORD PTR [EBP+08h], 0, hinst, 0
 mov    hlb, EAX
 INVOKE SendMessageA, hlb,LB_ADDSTRING,0,OFFSET ttekst1
 INVOKE SendMessageA, hlb,LB_ADDSTRING,0,OFFSET ttekst2
 INVOKE SendMessageA, hlb,LB_GETCOUNT,-1,offset ttekst
    
 
 

  wmLBUTTON:

 INVOKE SendMessageA,hlb,WM_GETTEXT,128,OFFSET bufor
 mov rr,EAX 
 INVOKE TextOutA,hDC,10,10,OFFSET bufor, rr
 mov EAX,0
 jmp konWNDPROC


  
;--- utworzenie okna edycyjnego ---
;INVOKE CreateWindowExA, 0, OFFSET tedt, OFFSET tnazwaedt,  EDTstyle, 10, 10, 200, 50, DWORD PTR [EBP+08h], 0, hinst, 0
 mov    hedt, EAX
; INVOKE SendMessageA, hedt,WM_SETTEXT,0,OFFSET ttekst
 
 ;INVOKE CreateSolidBrush,kolor
 ;mov hbrush,EAX
    
 

 
 
 
;--- utworzenie okna STATIC ---
 ;INVOKE CreateWindowExA, 0, OFFSET tstat, OFFSET tnazwastat,  STATstyle, 10, 150, 100, 40, DWORD PTR [EBP+08h], 0, hinst, 0
 ;mov    hstat, EAX
;---
 mov EAX,0
 jmp    konWNDPROC 
wmDESTROY:
 INVOKE DeleteObject, hbrush
 INVOKE PostQuitMessage, 0    ; wysyłanie WM_QUIT
 mov    EAX, 0
 jmp    konWNDPROC 
wmCOMMAND:
 mov EAX,hbutt
 cmp EAX,DWORD PTR [EBP+14h] ;czy LPARAM komunikatu WM_COMMAND = hbutt?
 je @F
 jmp et1
@@:  
 cmp znaczn,1
 je @F
 mov znaczn,1
 INVOKE SelectObject,hDC,hbrush
 mov holdbrush,EAX
 INVOKE FillRect,hDC,OFFSET rt,hbrush
 mov    EAX, 0
 jmp konWNDPROC
@@:          
 mov znaczn,0
 INVOKE SelectObject,hDC,holdbrush
 mov hbrush,EAX
 INVOKE FillRect,hDC,OFFSET rt,holdbrush
 mov    EAX, 0
 jmp konWNDPROC
et1:
 jmp konWNDPROC
 
wmRBUTTON:
 jmp wmDESTROY
 

;--- zdejmowanie ze stosu
konWNDPROC:    
 pop    EDI
 pop    ESI
 pop    EBX
 pop    EBP    ; standardowy epilog
 ret    16    ; zwolnienie komórek stosu
WndProc    ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;--- start programu ---
Start:
;--- deskryptor aplikacji ----
 INVOKE GetModuleHandleA, 0
 mov    hinst, EAX
;--- wypełnienie struktury okna WNDCLASS
 mov EAX, hinst
 mov [wndc.clsHInstance], EAX
 mov [wndc.clsStyle], CSstyle
 mov [wndc.clsLpfnWndProc], OFFSET WndProc
 mov [wndc.clsCbClsExtra], 0 
 mov [wndc.clsCbWndExtra], 0 
 INVOKE LoadIconA, 0, IDI_APPLICATION    ; ikona
 mov [wndc.clsHIcon], EAX
 INVOKE LoadCursorA, 0,    IDC_ARROW ; kursor
 mov    [wndc.clsHCursor], EAX
 INVOKE GetStockObject, WHITE_BRUSH    ; tło
 mov [wndc.clsHbrBackground], EAX
 mov [wndc.clsLpszMenuName], 0
 mov DWORD PTR [wndc.clsLpszClassName], OFFSET cname
;--- rejestracja okna --- 
 INVOKE RegisterClassA, OFFSET wndc
 cmp    EAX, 0
 jne @F
 jmp    err0
@@:
;--- utworzenie okna głównego ---
 INVOKE CreateWindowExA, 0, OFFSET cname, OFFSET tytul,  WNDstyle, 50, 50, 600, 400, 0, 0, hinst, 0
 cmp    EAX, 0
 jne @F
 jmp    err2
@@:
 mov    hwnd, EAX
 INVOKE ShowWindow, hwnd, SW_SHOWNORMAL         
 INVOKE GetDC,hwnd
 mov hdc,EAX
 INVOKE lstrlenA,OFFSET naglow
 mov rozmN,EAX         
 INVOKE TextOutA,hDC,10,20,OFFSET naglow,rozmN         
 INVOKE UpdateWindow, hwnd
;--- pętla obsługi komunikatów
msgloop:
 INVOKE GetMessageA, OFFSET msg, 0, 0, 0
 cmp EAX, 0
 jne @F
 jmp    etkon
@@:        
 cmp    EAX, -1
 jne @F
 jmp    err0
@@:        
 INVOKE TranslateMessage, OFFSET msg
 INVOKE DispatchMessageA, OFFSET msg
 jmp    msgloop
;--- obsługa błędów ---------
err0:
;--- okno z komunikatem o błędzie----
 INVOKE MessageBoxA,0,OFFSET terr,OFFSET nagl,0
 jmp    etkon
err2:
;--- okno z komunikatem o błędzie----
 INVOKE MessageBoxA,0,OFFSET terr2,OFFSET nagl,0
 jmp    etkon
;--- zakończenie procesu ---------
etkon:
 INVOKE ExitProcess, [msg.msWPARAM]
_TEXT    ENDS
END Start

Z góry dziękuje za pomoc ;)

0

To jest MASM32? To czemu ten kod taki nieczytelny? I co to znaczy kopiuje tekst? Bo ja domyślam się że chcesz pobrać tekst zaznaczonej pozycji go gdzieś wyświetlić tu masz przykład:

.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   
   includelib user32.lib
   includelib kernel32.lib

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.data
   ClassName db "MainWinClass",0
   AppName  db "Main Window",0
   ListBoxClassName db "ListBox",0
   Item1 db "Item 123", 0
   Item2 db "Item 23", 0
   Item3 db "Item 3", 0
.data?
   hInstance HINSTANCE ?
   CommandLine LPSTR ?
   hListBox dd ?
.code

; ---------------------------------------------------------------------------

start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	
	invoke GetCommandLine
	mov    CommandLine,eax
	
	invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
	invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
	LOCAL hwnd:HWND
	
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW
	mov   wc.lpfnWndProc, OFFSET WndProc
	mov   wc.cbClsExtra,NULL
	mov   wc.cbWndExtra,NULL
	push  hInstance
	pop   wc.hInstance
	mov   wc.hbrBackground,COLOR_BTNFACE+1
	mov   wc.lpszMenuName,NULL
	mov   wc.lpszClassName,OFFSET ClassName
	
	invoke LoadIcon,NULL,IDI_APPLICATION
	mov   wc.hIcon,eax
	mov   wc.hIconSm,eax
	
	invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax
	
	invoke RegisterClassEx, addr wc
	INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,300,260,NULL,NULL,\
           hInst,NULL
	mov   hwnd,eax
	
	invoke ShowWindow, hwnd,SW_SHOWNORMAL
	invoke UpdateWindow, hwnd
	
	.WHILE TRUE
		invoke GetMessage, ADDR msg,NULL,0,0
		.BREAK .IF (!eax)
		invoke TranslateMessage, ADDR msg
		invoke DispatchMessage, ADDR msg
	.ENDW
	
	mov     eax,msg.wParam
	ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    LOCAL Buffer[32] :BYTE
    LOCAL Item :DWORD
	
	.IF uMsg==WM_DESTROY
		invoke PostQuitMessage,NULL
	.ELSEIF uMsg==WM_CREATE
	    invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ListBoxClassName,0,
              WS_VSCROLL or WS_VISIBLE or LBS_NOTIFY or \ 
              WS_BORDER or WS_CHILD or \
              LBS_HASSTRINGS or LBS_NOINTEGRALHEIGHT or \
              LBS_DISABLENOSCROLL,
              10,10,150,200, hWnd,0,hInstance,NULL
         mov hListBox, eax
         
        invoke SendMessage,hListBox,LB_ADDSTRING,0,ADDR Item1
        invoke SendMessage,hListBox,LB_ADDSTRING,0,ADDR Item2
        invoke SendMessage,hListBox,LB_ADDSTRING,0,ADDR Item3        
    .ELSEIF uMsg==WM_COMMAND
        mov eax, lParam
        .iF eax == hListBox ;czy chodzi o nasz listbox (a nie inny lub w ogole inna kontrolke)
           movzx eax,word ptr wParam+2 ;czyli po prostu HIWORD wParam bo tam jest kod powiadomienia
           .iF eax == LBN_SELCHANGE ;zmieniono zaznaczenie
            	invoke SendMessage,hListBox,LB_GETCURSEL,0,0 ;ktory Item zaznaczony
            	mov Item, eax
            	invoke SendMessage,hListBox,LB_GETTEXT,Item,ADDR Buffer ;pobranie zaznaczonego tekstu
            	invoke SetWindowText,hWnd, ADDR Buffer ;wyswietl jako tytul okna        
           .ENDIF  
        .ENDIF   
	.ELSE
		invoke DefWindowProc,hWnd,uMsg,wParam,lParam		
		ret
	.ENDIF
	
	xor eax,eax
	ret
WndProc endp

end start

Ważne aby to zrobić w ten sposób ListBox musi mieć styl LBS_NOTIFY pozostałe istotne do pobrania tekstu (ja go w przykładzie wyświetlam jako tytuł okna) jest w obsłudze WM_COMMAND i opatrzyłem komentarzami.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.