Mikl___ Мне кажется что ”Шаг четвертый. Минимизируем WndProc (продолжение) Способ восьмой“ как раз один из самых неудачных. Потому что запись в таблицу адресов является довольно таки объёмным и медленным делом плюс, чем больше будет использовано сообщений, тем всё более неэффективным будет становиться этот способ из-за разрастания кода. Ведь вдобавок к большой таблице в памяти добавится большой код. Поэтому “Способ седьмой” будет, наверное, наиболее, эфиктивным. Тем более его можно чуть улучить?, правда смещение будет ограничено 16-тью битами: Код (Text): wmsg dd ? Max_MsgTable = 3 MsgTable dw defframeproc-defframeproc,wm_command-defframeproc,wm_close-defframeproc ;. . . mov eax,[wmsg] cmp ax,Max_MsgTable ja defframeproc; lea esi,[MsgTable+eax*2] lodsw add eax,defframeproc jmp eax; defframeproc: wm_command: wm_close: “hInstance dd 400000h ;Адрес нашей проги в памяти (Windows всегда её грузит по этому адресу) hIcon dd 10003h ;Иконка окна по умолчанию hCursor dd 10011h ;Курсор окна по умолчанию (здесь указан ID обычной стрелки)” А не является использование этих величин опасным ведь они недокументированны в MSDN и поэтому не гарантировано что их можно будет использовать после, какого ни будь патча?
hapr Собственно, способ седьмой и способ восьмой -- это одно и тоже, просто в описание восьмого способа более детализировано. О том что Я собственно и предупреждал Запись в таблицу адресов будет происходить лишь однократно в момент инициализации и далее для доступа к обработчику сообщения понадобится всего одно сравнение с Max_Msg. Спасибо за подсказку по уменьшению таблицы MsgTable в два раза, хотя наверное по аналогии можно уменьшить и до байта, если сообщения распреднлить по адресам кратным 2 или 4. Второе замечание о том что Проверялось для Win 95/98/2k/XP/Vista, наверное стало стандартом дефакто и врят ли изменится после, какого нибудь патча
Mikl___ , у тебя одного дома коллекйия твоих примеров и постов по этой теме. Можешь сделать chm архив и выкладывать его + дополнение? Совсем нехорошо пробегать по всей ветке темы вычесывая примеры. И, если можно, на какой-нить общедоступный свой блог / сайт / или сюда в раздел васма выкладывайте. спсибо.
ltshck Обрати внимание на сообщение #157 -- да и нет у меня дома коллекции примеров -- всё что приходит в голову выкладываю в этой ветке...
Mikl___ Я подразумевал под разрастанием кода, что имеет смысл, чтоб таблица была заполнена изначально, так как при записи адресов в таблицу, хоть и только при инициализации мы ничего особо не выиграем. Например, если использовать dw, то получаем : MsgTable dw 4 dup(?); экономим 8 байт на размере файла, но ведь в оперативной памяти эта таблица всё равно займёт 8 байт. mov [MsgTable], WM_PAINT; 6*4=24 байта (Интересно, а как правильна, определять, сколько места занимает команда процессора, а то в Fasm она занимает 6, а OLLYDBG показывает, что 9 байт?) А так как я понимаю исполняемый код тоже держится в памяти то получаем хоть и некоторую экономию на самом файле но зато большие потери на оперативной памяти, которая как я понимаю, является более ценной, чем место на жёстком диске, причём это сомнительное преимущество будет стремиться к нулю при увеличении обрабатываемых сообщений и кучности этих сообщений. Вдобавок достаточно медленная инициализация программы из за цикла с stosd с медленной записью в память, а ведь если надо заполнить несколько таких таблиц. Поэтому из за этого загрузка приложения может значительно замедлится. Уменьшение до байта врядли имеет смысл, так как в случаи, например кратности 4 полученное смещение будет слишком малым чтоб туда можно было всунуть код обработки сообщений.
hapr Первое сообщение в этой ветке начинается с фразы Имелось в виду минимальный размер программы на диске, что собственно и является одним из преимуществ ассемблера над ЯВУ. При работе с gui-приложениями, особенно учебными, добится большой скорости наверное и нельзя, и нецелесообразно, хотя stosd, при желании, можно заменить на более скоростную комбинацию mov [edi],eax/add edi,4. так что больший размер, который код программы займет в оперативной памяти, с этой точки зрения, меня волнует меньше, чем размер исполнимого кода на винчестере, хотя даже если моя программа занимает 1 байт, то на диске она займет 4 кбайта, но здесь это не принципиально. Уменьшение размера приложения, как раз и позволяют использовать таблицу состоящую из байтов, здесь требуется подгонка под конкретное приложение. [offtop]Построение фраз наталкивает на мысль, что вы с Украины или Болгарии?[/offtop]
Mikl___ Я просмотрел уроки по MDI на Fasm и Masm и у меня возникли некоторые замечания, вопросы?: В случае, когда после RegisterClass сразу следует CreateWindowEx то наверное, имеет смысл передавать вторым параметром “атом класса” который возвращает RegisterClass. А если вместо mov eax,[uMsg] так mov ax,word [uMsg] где [uMsg] – полученное сообщение. При получении WM_SIZE, зачем получать ширину и высоту рабочей области с помощью GetClientRect, если можно получить из lParam. [offtop] Честно говоря, я думал, что можно отличить по ”говору”, но, а так я с Белоруссии [/offtop]
hapr Исправление в 32 уроке по MDI Код (Text): wmSIZE: mov edx,[lParam] mov ax,dx; был eax равен 0 shr edx,16 invoke MoveWindow,[hClient],ebx,ebx,eax,edx,TRUE wmBYE: leave retn 10h Результат как и с GetClientRect, но код уменьшился -- здорово!
Mikl___ Так же, наверное, имеет смысл, например, при обработке сообщения WM_RBUTTONDOWN получать экранные координаты курсора не с помощью GetCursorPos, а из структуры MSG в которой находится позиция курсора, в экранных координатах, в момент, когда сообщение было помещено в очередь.
хочу спросить, если можно. Взял из этого топика примеры под fasm, конкретно Tut_21:pipe Попробовал начать переделывать, с целью уменьшения размера исходного кода , и чтобы понять ничего почти не менял, добавил только зацикливание в том месте где читается из пайпа, и импрорт по другому оформил. Теперь запускается только если вставляю строку "section '.data' data readable writeable", и размер exe прибавляется на килобайт, секция с данными оказывается в начале Я так понял это выравниванием как-то называется ? как сделать чтобы и дальше работало без .data типа db 0,0,0,0,0 придётся вставить перед данными ? (прикрепил сорц на всякий случай) По форуму искал, находил, но ничего не понял, как сделать, только какието /align для компоновщиков
оказалось что просто надо было добавить section '.code' code readable writeable executable и всётаки можно ещё уменьшить попробовал навставлять туда использование RICHEDIT вместо EDIT стало 2.5 килобайта
hapr Экранные координаты можно получать и из самого WM_RBUTTONDOWN (+ ClientToScreen либо MapWindowPoints). Но думаю, вы и сами сможете составить забавную демку-контрпример, раздувающую для наглядности разницу во времени между поступлением сообщения в очередь и выводом его в оконную процедуру.
xx7 1) xchg ebx,eax это не просто перестановка содержимого регистров, а обнуление регистра ebx одним байтом (xor ebx,ebx - это два байта) здесь учитывается, что при старте приложения в WinXP eax=0 2) mov esi,400000h ; [hInstance] shl esi,9 ; [hInstance]<<9 здесь после передачи значения hInstance, через esi передается значение CW_USEDEFAULT=80000000h=200h*400000h для установки X-, Y-координат и nWidth и nHeight окна
kero Конечно, можно, но если я не ошибаюсь, координаты помещаются в WM_RBUTTONDOWN в момент помещения сообщения в очередь соответственно, зачем преобразовать, если можно взять готовые. Но ведь не в каждой программе эта разница будет заметна, например: в “Блокноте”. В случае же более “серьёзных” программ можно использовать GetCursorPos но ведь если появляется разница во времени между поступлением сообщения и обработкой его, то соответственно на это время приложение перестанет отвечать на действия пользователя. Поэтому, наверное, имеет смысл в случаи длительных операций запускать их в отдельном потоке, что позволит использовать координаты из структуры MSG.
Mikl___, Спасибо! В дистрибутиве m32v10r.zip тоже есть подобные примеры masm32/examples/exampl02: showbmp, splash не знаю есть ли различие от Iczelion'а, просто может тоже быть полезным? PROTO - меня сразу же убило, что с ним делать я не осилю лучше подожду.
Mikl___, извини, но масм? Он же в туторах Zелона есть, хотя да у тебяж он оптимизированный наверно. Но fasm тоже жду. Сразу заодно спрошу... А GIF вообще не поддерживается в клиентскую область окна и вообще как ресурс? В том плане чтоб анимированный расунок подгрузить? Или это можно показом разных битмэпов изобразить средствами асма?