Занести в таблицу смещения меток. На FASM

Тема в разделе "WASM.BEGINNERS", создана пользователем Adrax, 2 июл 2007.

  1. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 leo
    Спасибо, что подсказали! Я и не знал, что имеет место такая замена:dntknw:
    Заменил все ret внутри Procedura на db 0C3h... Заработали почти все пункты меню, нажатие на Open вызывает диалог открытия файла, но при попытке самого открытия прога валится с исключением в kernel32.dll... Нажатие на Save, как и раньше, валит прогу с access violation в user32.dll...

    2 q_q
    Спасибо! Да, там же действительно 76 байт... А меня глюкануло, что 40...
    Кстати, не подскажете, а в FASM есть SIZEOF? - чтобы в следующий раз так не проколоться...

    2 IceStudent
    Наверное, на джампах было бы проще, вы правы... Но ведь всё казалось таким логичным:
    вызов из указанного места - возврат обратно! А теперь я сам уже никакой логики не наблюдаю:dntknw:
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    а в FASM есть SIZEOF?
    Да.
    Код (Text):
    1. ...
    2. ;; в сегменте данных
    3. ofn OPENFILENAME sizeof.OPENFILENAME,0,0,filter,0,0,0,buffer,260,0,0,0,0,0,0,0,0,0,0,0
    4. ...
    5. ;; в коде
    6. mov eax,sizeof.OPENFILENAME
    7. ...
    А теперь я сам уже никакой логики не наблюдаю
    Не стОит злоупотреблять jmp'ами. Используй подпрограммы, только не "внутри" других.
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Adrax
    Зачем ? Для этого есть мнемоника retn, которую никакие макросы не переопределяют
     
  4. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 leo
    Вы правы! Я так и сделаю

    Я нашёл, где протупил!
    Исходник я подправил, получилось вот что:
    Код (Text):
    1. format PE GUI 4.0
    2. include 'win32axp.inc'
    3. include 'encoding\WIN1251.INC'
    4. ;это на будущее - чтоб надписи на русском были
    5.  
    6. ID_MENU = 700h
    7. ID_ACCEL = 701h
    8. ID_ABOUT = 702h
    9. ID_ICON = 703h
    10.  
    11. EditID = 1
    12.  
    13. .data
    14.  
    15.   name db 'RFpad',0
    16.   editK db 'edit',0
    17.   changes db 'Do you want to save changes?',0
    18.  
    19.  filter  db  "All Files",0,'*.*',0
    20.          db  "Text Files",0, '*.txt',0,0
    21.  
    22.   wc WNDCLASS 0,Procedura,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,ID_MENU,name
    23.  
    24.   ofn OPENFILENAME sizeof.OPENFILENAME,0,0,filter,0,0,2,buffer,259,0,0,0,0,0,0,0,0,0,0,0
    25.  buffer rb 260
    26.   newflag db 1
    27.   edith dd ?
    28.   pmem dd ?
    29.   accelh dd ?
    30.   sizeRW dd ?
    31.   hmem dd ?
    32.   filesize dd ?
    33.   client RECT
    34.   msg MSG
    35.  
    36. table dd NEW
    37.       dd OPEN
    38.       dd SAVE
    39.       dd SAVEAS
    40.       dd EXIT
    41.       dd ABOUT
    42.       dd UNDO
    43.       dd CUT
    44.       dd COPY
    45.       dd PASTE
    46.       dd CLEAR
    47.       dd SETSEL
    48.  
    49. .code
    50.  
    51.   fuck:
    52.         invoke GetCommandLine
    53.         mov edi,eax
    54.         mov al,20h
    55.         mov ecx,260
    56.         repne scasb
    57.         cmp byte [edi],0
    58.         je cmdline_empty
    59.         mov esi,edi
    60.         mov edi,buffer
    61.         rep movsb
    62.         mov [newflag],0
    63.  cmdline_empty:
    64.         invoke  GetModuleHandle,0
    65.         mov     [wc.hInstance],eax
    66.         invoke  LoadIcon,[wc.hInstance],ID_ICON
    67.         mov     [wc.hIcon],eax
    68.         invoke  LoadCursor,0,IDC_ARROW
    69.         mov     [wc.hCursor],eax
    70.         invoke  RegisterClass,wc
    71.         invoke  CreateWindowEx,0,name,name,WS_VISIBLE+WS_OVERLAPPEDWINDOW,128,128,192,192,NULL,NULL,[wc.hInstance],NULL
    72.         invoke LoadAccelerators,[wc.hInstance],ID_ACCEL
    73.         mov [accelh],eax
    74.  
    75.  
    76.   msg_loop:
    77.         invoke  GetMessage,msg,NULL,0,0
    78.         or      eax,eax
    79.         jz      end_loop
    80.  
    81.         invoke TranslateAccelerator,[wc.hInstance],[accelh],msg
    82.         test eax,eax
    83.         jnz msg_loop
    84.  
    85.         invoke  TranslateMessage,msg
    86.         invoke  DispatchMessage,msg
    87.         jmp     msg_loop
    88.   end_loop:
    89.         invoke  ExitProcess,[msg.wParam]
    90.  
    91. proc Procedura hwnd,wmsg,wparam,lparam
    92.         push ebx
    93.         push esi
    94.         push edi
    95.         cmp [wmsg],WM_COMMAND
    96.         je Command
    97.         cmp [wmsg],WM_SIZE
    98.         je Siz
    99.         cmp [wmsg],WM_ACTIVATE
    100.         je Act
    101.         cmp [wmsg],WM_CLOSE
    102.         je Close
    103.         cmp [wmsg],WM_CREATE
    104.         je Create
    105.         cmp [wmsg],WM_DESTROY
    106.         je Destroy
    107.      xx:
    108.         invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    109.         jmp finish
    110.  
    111.   Close:
    112.         call saving
    113.         jmp xx
    114.  
    115.   Create:
    116.         invoke GetClientRect,[hwnd],client
    117.         invoke CreateWindowEx,WS_EX_CLIENTEDGE,editK,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[client.left],[client.top],[client.right],[client.bottom],[hwnd],0,[wc.hInstance],NULL
    118.         test eax,eax
    119.         jz fail
    120.         mov [edith],eax
    121.         invoke SetFocus,eax
    122.         cmp [newflag],1
    123.         je continue
    124.         call getopen
    125.   continue:
    126.         xor eax,eax
    127.         jmp finish
    128.   fail:
    129.         or eax,-1
    130.         jmp finish
    131.  
    132.  Command:
    133.         cmp [lparam],0
    134.         jnz continue
    135.         mov eax,[wparam]
    136.         sub ax,100h
    137.         jb continue
    138.         cmp ax,0Bh
    139.         ja continue
    140.         call dword [table+eax*4]
    141.         jmp continue
    142.  
    143.  SETSEL:
    144.         invoke SendMessage,[edith],EM_SETSEL,0,-1
    145.         retn
    146.  
    147.  CLEAR:
    148.        mov eax,WM_CLEAR
    149.        jmp sendt
    150.  PASTE:
    151.         mov eax,WM_PASTE
    152.         jmp sendt
    153.  COPY:
    154.         mov eax,WM_COPY
    155.         jmp sendt
    156.  CUT:
    157.         mov eax,WM_CUT
    158.         jmp sendt
    159.  UNDO:
    160.         mov eax,EM_UNDO
    161.  sendt:
    162.         invoke SendMessage,[edith],eax,0,0
    163.         retn
    164.  
    165.  NEW:
    166.      call saving
    167.      mov [newflag],1
    168.      invoke SendMessage,[edith],WM_SETTEXT,0,0
    169.      retn
    170.  
    171.  ABOUT:
    172.       invoke MessageBox,[hwnd],'RFpad text editor by Adrax','RFpad',MB_OK
    173.       retn
    174.  
    175.  OPEN:
    176.       call saving
    177.       mov [ofn.Flags],OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_EXPLORER
    178.       invoke GetOpenFileName,ofn
    179.       test eax,eax
    180.       jz fileopenfailed
    181.  
    182.   getopen:
    183.         invoke CreateFile,buffer,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,0
    184.         mov edi,eax
    185.         invoke GetFileSize,edi,0
    186.         mov [filesize],eax
    187.         invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,eax
    188.         mov [hmem],eax
    189.         invoke GlobalLock,eax
    190.         mov [pmem],eax
    191.         invoke ReadFile,edi,[pmem],[filesize],sizeRW,0
    192.         invoke SendMessage,[edith],WM_SETTEXT,0,[pmem]
    193.         invoke GlobalUnlock,[pmem]
    194.         invoke GlobalFree,[hmem]
    195.         invoke CloseHandle,edi
    196.         mov [newflag],1
    197.   fileopenfailed:
    198.         invoke SetFocus,[edith]
    199.         retn
    200.  
    201.  SAVE:
    202.        cmp [newflag],1
    203.        jnz getsave
    204.  SAVEAS:
    205.        mov [ofn.Flags],OFN_EXPLORER or OFN_OVERWRITEPROMPT
    206.        invoke GetSaveFileName,ofn
    207.        test eax,eax
    208.        jz filesavefailed
    209.   getsave:
    210.        invoke CreateFile,buffer,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0
    211.        mov edi,eax
    212.        invoke SendMessage,[edith],WM_GETTEXTLENGTH,0,0
    213.        mov [filesize],eax
    214.        invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,[filesize]
    215.        mov [hmem],eax
    216.        invoke GlobalLock,eax
    217.        mov [pmem],eax
    218.        invoke SendMessage,[edith],WM_GETTEXT,[filesize],eax
    219.        invoke WriteFile,edi,[pmem],eax,sizeRW,0
    220.        invoke GlobalUnlock,[pmem]
    221.        invoke GlobalFree,[hmem]
    222.        invoke CloseHandle,edi
    223.        invoke SendMessage,[edith],EM_SETMODIFY,0,0
    224.        mov [newflag],0
    225. filesavefailed:
    226.         invoke SetFocus,[edith]
    227.         retn
    228.  
    229.  EXIT:
    230.       call saving
    231.       invoke DestroyWindow,[hwnd]
    232.       retn
    233.  
    234.  Siz:
    235.       invoke GetClientRect,[hwnd],client
    236.       invoke MoveWindow,[edith],[client.left],[client.top],[client.right],[client.bottom],TRUE
    237.       xor eax,eax
    238.       jmp finish
    239.  
    240.  Act:
    241.       invoke SetFocus,[edith]
    242.       xor eax,eax
    243.       jmp finish
    244.  
    245.  saving:
    246.       invoke SendMessage,[edith],EM_GETMODIFY,0,0;èçìåíÿëñÿ ëè òåêñò
    247.         test eax,eax
    248.         jz not_modified        
    249.         invoke MessageBox,[hwnd],changes,name,MB_YESNO + MB_ICONWARNING
    250.         cmp eax,IDYES
    251.         jne not_modified
    252.         call SAVE
    253. not_modified:
    254.         retn
    255.  
    256.   Destroy:
    257.         invoke  PostQuitMessage,0
    258.         xor eax,eax
    259.  
    260.   finish:
    261.         pop edi
    262.         pop esi
    263.         pop ebx
    264.         ret
    265. endp
    266.  
    267. section '.rsrc' resource from 'RFpad.res' data  readable
    268.  
    269. .end fuck
    Диалоги открытия/сохранения работают,но возникли новые проблемы:
    1. При сохранении обрезается последний символ, а при открытии - наоборот, читается три лишних. Понимаю, что неправильно определяю filesize, но уже задолбался методом тыка подбирать значения: на сколько уменьшить и на сколько увеличить при вызове разных функций. Эта переменная у меня ж ещё и в выделении памяти задействована...
    2. При сохранении не подставляется расширение .txt - как сделать?
    3. До сих пор не въехал в accelerators...
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    1. При сохранении обрезается последний символ
    WM_GETTEXTLENGTH возвращает размер без учета ноль-символа. WM_GETTEXT помещает буфер текст и ноль-символ. Увеличь размер буфера на единицу после WM_GETTEXTLENGTH.

    при открытии - наоборот, читается три лишних
    На самом деле не три, а до ноль-символа. WM_SETTEXT помещает в edit весь переданный буфер до первого ноль-символа. Увеличь размер на единицу буфера после GetFileSize.

    2. При сохранении не подставляется расширение .txt - как сделать?
    После GetSaveFileName можно проанализировать поле ofn.nFileExtension. Если оно равно нулю, то расширения нет, придется его lstrcat. Если оно не равно нулю, то надо анализировать байт buffer[ ofn.nFileExtension ], если он ноль, то пользователь ввел точку, если нет то пользователь ввел расширение. Как поступать в этих ситуациях решать тебе.

    3. До сих пор не въехал в accelerators
    Первый параметр TranslateAccelerator - дескриптор окна.
     
  6. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    Первый параметр TranslateAccelerator - дескриптор окна

    Попробовал уже... После CreateWindowEx сделал mov esi,eax, а потом - TranslateAccelerator,esi,[accelh],msg...
    Компилится, запускается... При нажатии Ctrl+A - падает:dntknw:

    С расширением почти разобрался. За советы - огромное спасибо!
     
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    Я забыл дописать
    Код (Text):
    1. ...
    2.         cmp [lparam],0
    3.         jnz continue
    4.         mov eax,[wparam]
    5.         and eax,0FFFFh                ;; !!!
    6.         sub ax,100h
    7.         jb continue
    8.         cmp ax,0Bh
    9.         ja continue
    10.         call dword [table+eax*4]
    11.         jmp continue
    12.  
    13. ...
     
  8. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    Огромное спасибо! Теперь всё работает!!

    Также спасибо leo, JAPH за разъяснение мне, глупому, элементарных вещей:)

    И, напоследок, ещё вопрос (знаю, что достал, но пожалейте новичка): я принялся забивать Edit текстом - влезает всего 24737 символов. С чем связано это ограничение и можно ли его обойти?
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Adrax
    Код (Text):
    1. invoke SendMessage, [h_edit], EM_SETLIMITTEXT, 0, 0
    будет влезать 65535 ;) больше нельзя - ограничение связано с разработкой контрола Edit в эпоху доисторического сюрреализма ;)) - если надо больше - переходи на RichEdit.
     
  10. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Y_Mur
    Cогласно описанию EM_LIMITTEXT/EM_SETLIMITTEXT под nt/2k/xp 64k не предел даже для single-line edit control.
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    q_q
    Ясно :)
    Я с этим ещё в 95й игрался и с тех пор не использую edit для больших текстов :) - хорошо, что баг пофиксили :)
     
  12. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Огромное спасибо q_q, leo,Y_Mur, JAPH!!!!
    Тему можно закрывать

    С помощью ваших советов я накодил простенький text editor на основе minipad
    Теперь буду его доусовершенствовать: прикручу поиск по тексту, диалог печати и прочие вкусности

    Ещё раз спасибо всем за дельные советы и железное терпение!!