Мегаобучалка Главная | О нас | Обратная связь


Каркасное Windows -приложение на ассемблере



2019-07-03 216 Обсуждений (0)
Каркасное Windows -приложение на ассемблере 0.00 из 5.00 0 оценок




Уральского государственного технического университета

 

Кафедра микропроцессорной техники

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

 

 

Оценка проекта

Члены комиссии

 

 

Программа демонстрирующая иерархию окон Windows

 

Курсовая работа

 

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

 

                                                                                                                             

Руководитель:                              Кулюкин В.П.

 

Слушатель гр.СП-923:               

 

                                                             2001г.

Содержание:

Введение

1. Окон­ные приложения Windows.

Каркасное Windows-приложение на ассемблере

Иерархия окон

Программа демонстрирующая иерархию окон Windows»

Библиографический список

 

Введение

 

 

В подавляющем большинстве книг о программировании для Windows изложение, как правило, ведется на базе языка C/C++, реже — на базе Pascal. А что же ас­семблер — в стороне? Конечно, нет! Мы не раз обращали ваше внимание на пра­вильное понимание места ассемблера в архитектуре компьютера. Любая програм­ма на языке самого высокого уровня в своем внутреннем виде представляет собой последовательность машинных кодов. А раз так, то всегда остается теоретическая возможность написать ту же программу, но уже на языке ассемблера: Непонима­ние или недооценка такой возможности приводит к тому, что достаточно часто приходится слышать фразу, подобную следующей: «Ах, опять этот ассемблер, но ведь это что-то несерьезное!» Также трудно согласиться с тезисом, который чаще всего следует вслед за этой фразой. Суть его сводится к утверждению того, что мощность современных компьютеров позволяет не рассматривать проблему эф­фективности функционирования программы в качестве первоочередной. Гораздо легче решить ее за счет увеличения объема памяти, быстродействия центрально­го процессора и качества компьютерной периферии. Чем обосновать необходимость разработки Windows-приложений на языке ассем­блера? Приведем следующие аргументы:

Ø  языке ассемблера позволяет программисту полностью контролировать создава­емый им программный код и оптимизировать его по своему усмотрению;

Ø компиляторы языков высокого уровня помещают в загрузочный модуль про­граммы избыточную информацию. Эквивалентные исполняемые модули, ис­ходный текст которых написан на языке ассемблера, имеют в несколько раз меньший размер;

Ø при программировании на ассемблере сохраняется полный доступ к аппарат­ным ресурсам компьютера;

Ø приложение, написанное на языке ассемблера, как правило, быстрее загружа­ется в оперативную память компьютера;

Ø приложение, написанное на языке ассемблера, обладает, как правило, более высокой скоростью работы и реактивностью ответа на действия пользователя. Разумеется, эти аргументы не следует воспринимать, как некоторую рекламную кампанию в поддержку языка ассемблера. Но нельзя забывать и о том, что суще­ствует бесконечное множество прикладных задач, ждущих своей очереди на ком­пьютерную реализацию. Далеко не все из этих задач требуют применения тяже­ловесных средств разработки, результатом работы которых являются столь же тяжеловесные исполняемые файлы. Многие прикладные задачи могут быть изящ­но исполнены на языке ассемблера, не теряя привлекательности.

1. Окон­ные приложения Windows .

Windows поддерживает два типа приложений:

Ø оконное приложение — строится на базе специального набора функций (API), составляющих графический интерфейс пользователя (GUI, Graphic User Inter­face). Оконное приложение представляет собой программу, которая весь вы­вод на экран производит в графическом виде. Первым результатом работы оконного приложения является отображение на экране специального объек­та — окна. После того как окно отображено на экране, вся работа приложения направлена на то, чтобы поддерживать его в актуальном состоянии;

Основной тип приложений в Windows — окон­ные, поэтому с них мы и начнем знакомство с процессом разработки программ для этой операционной системы.

Любое оконное Windows-приложение имеет типовую структуру, основу которой составляет так называемое каркасное приложение. Это приложение содержит ми­нимально необходимый программный код для обеспечения функционирования полноценного Windows-приложения. Не случайно во всех источниках в качестве первого Windows-приложения рекомендуется изучать и исследовать работу не­которого каркасного приложения, так как именно оно отражает основные особен­ности взаимодействия программы с операционной системой Windows. Более того, написав и отладив один раз каркасное приложение, вы будете использовать его в необходимую терминологию и сможем больше внимания уделить логике работы Windows-приложения, а не деталям его реализации.

Минимальное приложение Windows состоит из трех частей:

Ø  главной функции;

Ø  цикла обработки сообщений;

Ø  оконной функции.

Выполнение любого оконного Windows-приложения начинается с главной функ­ции. Она содержит код, осуществляющий настройку (инициализацию) приложе­ния в среде операционной системы Windows. Видимым для пользователя резуль­татом работы главной функции является появление на экране графического объекта в виде окна. Последним действием кода главной функции является со­здание цикла обработки сообщений. После его создания приложение становится пассивным и начинает взаимодействовать с внешним миром посредством специ­альным образом оформленных данных — сообщений. Обработка поступающих приложению сообщений осуществляется специальной функцией, называемой оконной. Оконная функция уникальна тем, что может быть вызвана только из операционной системы, а не из приложения, которое ее содержит. Таким образом, Windows-приложение, как минимум, должно состоять из трех перечис­ленных элементов.

Каркасное Windows-приложение на ассемблере содержит один сегмент данных .data и один сегмент кода . code. Сегмент стека в исходных текстах Windows-приложений непосредственно описывать не нужно. Windows выделяет для стега объем памяти, размер которого задан программистом в файле с расширением . def. Текст листинга 2 достаточно большой. Поэтому для обсуждения разобьем erо комментариями на характерные фрагменты, каждый из которых затем поясним необходимой степенью детализации.

Каркасное Windows -приложение на ассемблере

 

<1> ;Пример каркасного приложения для Win32

<2> .386

<3> locals         ;разрешает применение локальных меток в программе

<4> .model flat, STDCALL  ;модель памяти flat Я

<5> ;STDCALL - передача параметров в стиле С (справа налево),

<6> ; вызываемая процедура чистит за собой стек Ш

<7> include windowA.inc    ;включаемый файл с описаниями базовых структур

                                               ;и констант Win32 т

<8> ;Объявление внешними используемых в данной программе функций Win32 (ASCII):    

<9> extrn        GetModuleHandleA:PROC

<10> extrn       GetVersionExA:PROC В

<11> extrn        GetCommandLineA:PROC

<12> extrn        GetEnvironmentStringsA:PROC

<13> extrn        GetEnvironmentStringsA:PROC

<14> extrn        GetStartupInfoA:PROC

<15> extrn        LoadIconA:PROC

<16> extrn        LoadCursorA:PROC

<17> extrn        GetStockObject:PROC

<18> extrn        RegisterClassExA:PROC

<19> extrn        CreateWindowExA:PROC

<20> extrn        ShowWindow:PROC

<21> extrn        UpdateWindow:PROC

<22> extrn        GetMessageA:PROC

<23> extrn       TranslateMessage:PROC

<24> extrn        DispatchMessageA:PROC

<25> extrn        ExitProcess:PROC            

<26> extrn        PostQuitMessage:PROC

<27> extrn        DefWindowProcA:PROC

<28> extrn        PlaySoundA:PROC

<29> extrn         ReleaseDC:PROC

<30> extrn        TextOutA:PROC  

<31> extrn        GetDC:PROC

<32> extrn        BeginPaint:PROC

<33> extrn       EndPaint:PROC

<34> ;объявление оконной функции объектом, видимым за пределами данного кода

<35> public WindowProc

<36> .data

<37> hwnd         dd      0

<38> hInst             dd      0

<39> hdc                dd      0

<40> ;lpVersionInformation OSVERSIONINFO <?>

<41> wcl  WNDCLASSEX <?>

<42> message MSG <?>

<43> ps  PAINTSTRUCT <?>

<44> szClassName db 'Приложение Win32 ',0

<45> szTitleName db 'Каркасное приложение Win32 на ассемблере'.0

<46> MesWindow db 'Это процесс разработки приложения

 на ассемблере?'

<47> MesWindowLen= $-MesWindow

<48> playFileCreate  db 'create.wav',0

<49> playFilePaint    db 'paint.wav',0

<50> playFileDestroy db 'destroy.wav',0

<51> . code

<52> start proc near

<53> ;точка входа в программу:

<54> ;начало стартового кода

<55> ;вызовы расположенных ниже функций можно при необходимости раскомментировать,

<56> :но они не являются обязательными в данной программе

<57> ;вызов BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInformation)

<58> ;   push offset lpVersionInformation

<59> ;   call GetVersionExA

<60> ;далее можно вставить код для анализа информации о версии Windows

<61> ;вызов LPTSTR GetCommandLine(VOID) - получить указатель на командную строку

<62> ;  call GetCommandLineA :врегистре еах адрес

<63> ;вызов LPVOID GetEnvironmentStrings (VOID) - получить указатель

 ;на блок с переменными окружения

<64> ;  call GetEnvironmentStringsA ;врегистре еах адрес

<65> ;вызов VOIDGetStartupInfo(LPSTARTUPINFO lpStartupInfo) ;указатель

 ;на структуру STARTUPINFO

<66> ;  push offset lpStartupInfo

<67> ;  call GetStartupInfoA

<68> ;вызов HMODULE GetModuleHandleA (LPCTSTR lpModuleName)

<69> push NULL ;0->GetModuleHandle

<70> call GetModuleHandleA ;получить значение базового адреса,

<71> mov hInst, eax ;no которому загружен модуль.

<72> ;далее hInst будет использоваться в качестве дескриптора данного приложения

<73> ;конец стартового кода

<74> WinMain:

<75>;определить класс окна ATOM RegisterClassEx(CONST WNDCLASSEX *lpWndClassEx),

<76> ;             где *lpWndClassEx - адрес структуры WndClassEx

<77> ;для начала инициализируем поля структуры WndClassEx

<78> mov wcl.cbSize,typeWNDCLASSEX -.размер структуры

 :в wcl.cbCIZE

<79> mov wcl.style,CS_HREDRAW+CS_VREDRAW  

<80> mov wcl.pfnWndProg,offsetWindowProg ;адрес оконной процедуры

<81> mov wcl.cbCisExtra,0

<82> mov wcl.cbWndExtra,0

<83> mov eax,hInst

<84> mov ;дискриптор приложения в поле hInstance структуры wcl

<85> mov wcl.hInstance, eax

<86> ;готовим вызов HICON LoadIcon (HINSTANCE hInstance, LPCTSTR lpIconName)

<87> push IDI_APPLICATION ,-стандартный значок

<88> push 0 ;NULL

<89> саП LoadIconA

<90> mov wcl.hIcon, eax ,-дескриптор значка в поле hIcon I

;структуры wcl

<91> ;готовим вызов HCURSOR LoadCursorA (HINSTANCE hInstance, LPCTSTR M ;lpCursorName)

<92> push IDC_ARROW ,-стандартный курсор - стрелка

<93> push 0

<94> саll LoadCursorA

<95> mov wcl.hCursor,eax ;дескриптор курсора в поле hCursor

;структуры wc1

<96> ;определим цвет фона окна - белый

<97> ;готовим вызов HGDIOBJ GetStockObject(int fnObject)

<98> push WHITE_BRUSH

<99> саП GetStockObject

<100> mov wcl.hbrBackground, eax

<101> mov dword ptrwcl.lpszMenuName, 0 ;без главного меню

<102> mov dwordptrwcl.lpszClassName,offsetszC1assName; имя

;класса окна  

<103> mov wcl.hIconSm, 0

<104> ;регистрируем класс окна - готовим вызов RegisterClassExA (&wndclass)

<105> push offset wcl

<106> саП RegisterClassExA

<107> test ax, ах;проверить на успех регистрации класса окна

<108> jz end_cyc1_msg ;неудача

<109> ;создаем окно:

<110> ;готовим вызовHWND CreateWindowExA(DWORDdwExStyle,

 LPCTSTR1pClassName,

<111> ; LPCTSTR 1pW1ndowName, DWORD dwStyle, int x, int у, int nWidth,

        |;int nHeight,

<112> ; HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID      

        ;lpParam)

<113> push 0 ;lpParam                         

<114> push hInst ;hInstance     

<115> push NULL ;menu

<116>    push NULL ;parent hwnd

<117> push CW_USEDEFAULT ;высота окна

<118> push CW_USEDEFAULT ;ширина окна

<119>  push CW_USEDEFAULT ;координата у левого верхнего угла

      ;окна

<120>  push CW_USEDEFAULT ;координата х левого верхнего угла

<121>  push WS_OVERLAPPEDWINDOW ;стиль окна

<122>  push offset szTitleName ;строка заголовка окна

<123>  push offset szClassName ;имя класса окна

<124>  push NULL

<125> саll CreateWindowExA

<126>  mov hwnd,eax ;-дескриптор окна

<127>  ;показать окно:

<128>   ;готовим вызов BOOL ShowWindow( HWND hWnd, int nCmdShow )

<129> push SW_SHOWNORMAL

<130> push    hwnd

<131> call    ShowWindow

<132> ;перерисовываем содержимое окна

<133> ;готовим вызов BOOL UpdateWindow( HWND hWnd )

<134> push    hwnd

<135> call     UpdateWindow

<136> ;запускаем цикл сообщений:

<137> ;готовим вызов BOOL GetMessageA( LPMSG lpMsg, HWND hWnd,

<138> ;                UINTwMsgFilterMin,UINTwMsgFilterMax)

<139> cycl_msg:

<140> push    0

<141> push    0

<142> push    NULL

<143> push    offset message

<144> cal 1    GetMessageA

<145> cmp      ах, 0

<146> je       end_cycl_msg

<147> ;трансляция ввода с клавиатуры

<148> ;готовим вызов BOOL Trans1ateMessage( CONST MSG *lpMsg )

<149> push    offset message

<150> call    TranslateMessage

<151> ;отправим сообщение оконной процедуре

<152> ;готовим вызов LONG D1spatchMessage( CONST MSG *lpmsg )

<153> push     offset message

<154> call     DispatchMessageA

<155> jmp      cycl_msg

<156> end_cycl_msg:

<157>

<158> ;выход из приложения

<159> ;готовим вызов VOID ExitProcess( UINT uExitCode )

<160> push    NULL

<161> call     ExitProcess

<162> start       endp

<163> ; - - - - - - - - - - - - --WindowProc-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

<164> WindowProc proc

<165> argP0nwnd:DWORD, PPmes:DWORD, @@wparam:DWORD, @@lparam:DWORD

<166> uses ebx, edi, es1   ;эти регистры обязательно должны сохраняться

<167> local         @@hdc:DWORD

<168> cmp      @@mes, WM_DESTROY

<169> je       wmdestroy

<170> cmp      @@mes, WM_CREATE

<171> je       wmcreate

<172> cmp      @@mes, WM_PAINT

<173> je       wmpaint

<174> jmp      default

<175> wmcreate:

<176> ;обозначим создание окна звуковым эффектом

<177> ;готовим вызов функции BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD

 ;fdwSound )

<178> push     SND_SYNC+SND_FILENAME

<179> push    NULL

<180> push    offset playFileCreate

<181>   call PlaySoundA

<182>    mov eax, О;возвращаемое значение - 0

<183>    jmp exit_wndproc

<184> wmpaint:

<185>        push SND_SYNC+SND_FILENAME

<186>    push NULL

<187>    push offset playFIilePaint

<188>    call P1aySoundA

<189>;получим контекст устройства HDC BeginPaint(HWND nwnd,LPPAINTSTRUCT;LPpAINT)

<190>    push offset ps

<191>       push @@hwnd

<192>    call BeginPaint

<193>    mov @@hdc,eax

<194> ;выведем строку текста в окно BOOL TextOut( HDC hdc. int nXStart, int

:nYStart.

<195> ;  LPCTSTR lpString, int cbString )

<196>    push MesWindowLen

<197>    push offset MesWindow

<198>    push 100

<199>    push 10

<200>    push @@hdc

<201>    call TextOutA

<202> :ocвoбoдитькoнтeкcтBOOLEndPaint( HWNDhWnd, CONSTPAINTSTRUCT*lpPai <203>    push offset ps

<204>    push @@hdc

<205>    call EndPaint

<206>    mov еах,0;возвращаемое значение-0

 <207>    jmp exit_wndproc

 <208> wmdestroy:

<209>    push SND_SYNC+SND_FILENAME

<210>    push NULL

 <211>    push offset playFileDestroy

<212>    call PlaySoundA

<213> ;послать сообщение WМ_QUIТ

<214> ;готовим вызов VOID PostQuitMessage( int nExitCode )

<215>    push 0

<216>    call PostQuitMessage

<217>    mov eax, О;возвращаемое значение - 0

<218>    jmp exit_wndproc

<219> default:

<220> ; обработка по умолчанию

<221>;готовим вызов LRESULTDefWindowProc( HWND hWnd, UINTMsg,

<222> ;   WPARAMwParam,LPARAMlParam)

<223>    push @@lparam

 <224>    push @@wparam

<225>    push @@mes

<226>    push @@nwnd

 <227>    call DefWindowProcA

 <228>    jmp exit_wndproc

<229> ;... ... ...

<230> exit_wndproc:

<231> ret

<232> WindowProc endp

<233> end           start

 

Иерархия окон

 

Изучив по дисциплине «Системное программное обеспечение» написание окон Windows на языке Assembler и рассматривая графическую оконную систему нельзя обойтись без подробного рассмотрения того, какие окна можно отображать на экране.

Тип окна задается 32-битовым без знаковым целым числом, которое указывается третьим параметром вызова функции Create Window.

       Существует всего лишь три основных типа окон Window.

1 тип. Перекрывающиеся окна. Флаг WS_OVERLAPPED.

2 тип. Вспомогательные окна. Флаг WS_POPUP.

3 тип. Дочерние окна. . Флаг WS_CHILD.

Для написания курсового проекта, который имеет тему «Программа демонстрирующая иерархию окон Windows» были использованы именно эти типы окон.

       Нужно о них помнить следующее что:

· Перекрывающееся окно никогда не имеет родителя

· Дочернее окно всегда имеет родителя.

· Вспомогательное окно может иметь и не иметь родителя; если оно имеет родителя, то все равно это не дочернее, а вспомогательное окно.

Из всех концепций системы управления окнами наиболее фундаментальной является отношение предок/ потомок/ сосед. Как мы видели при описании структуры данных WND, каждое окно содержит логический номер окна своего предка, логический номер своего первого дочернего окна и логический номер следующего соседнего окна. Соседними являются окна, имеющие одинаковое родительское окно. В действительности значения HWND являются просто ближними указателями в локальной "куче" модуля USER, поэтому вы можете рассматривать их как указатели связного списка, которые позволяют обходить пути в иерархии окон. Иерархия окон, создаваемая модулем USER, показана на рис.1.

Иерархия окон обходится во всех трех направлениях - от предка к потомку, от потомка к предку и от соседа к соседу. Примеры обхода иерархии включают следующее:

• При уничтожении окна модуль USER должен уничтожить всех его потомков, а также их потомков. USER обходит всю иерархию, используя поля hWndChild и hWndNext- Напомним, логические номера окон являются просто ближними указателями в локальной "куче" модуля USER.

• Когда происходит передача фокуса ввода при нажатии клавиши Tab между элементами управления в окне диалога (которые являются потомками окна диалога), указатели на соседнее окна (или поле hWndNext) соединяют друг с другом элементы управления. Кроме того, упорядочение окон в списке hWndChild и hWndNext отражает Z-порядок окон на экране. Z-порядок представляет собой относительную позицию окон в третьем измерении (в направлении от экрана к вам). Если вы щелчком кнопки мыши выбираете различные основные окна;

чтобы поместить их в вершину Z-порядка, их относительные позиции в списке hWndNext сдвигаются.                                                            

 

 

 

Рис..1 Иерархия окон, созданная модулем USER.

 

• Когда с помощью щелчка кнопки мыши вы выбираете диалоговое управляющее окно, это приводит к тому, что менеджер диалогов просмаривает цепочку указателей предка, чтобы посмотреть, необходимо ли сделать активным окно приложения верхнего уровня (основное).

В корне дерева окон находится desktop-окно. Это окно покрывает весь экран и всегда находится на вершине Z-порядка. Это означает, что оно всегда находится позади всех других окон. Desktop-окно является первым созданным окном, и это единственное окно в системе, которое не имеет окна родителя или владельца. (Окна-владельцы описаны далее.) Окраска окна фона отвечает за "обои" Windows.

Desktop-окно ничем особенным не выделяется в смысле установки специальных битов или т.п. Оно создается с битами стиля (обсуждаются ниже) WS_POPUP и WS_CLIPCHILDREN. Нет никакого недокументированного бита стиля WS_DESKTOP. Вместо этого логический номер desktop-окна сохраняется в глобальной переменной модуля USER с именем HWndDesktop. Когда системе управления окнами нужно знать, имеет ли она дело с desktop-окном, она просто сравнивает HWND, о котором идет речь, с HWndDesktop. Вы можете получить значение переменной HWndDesktop, используя документированную API-функцию GetDesktopWindow().

ВЛАДЕНИЕ ОКНАМИ В Windows

Наряду с отношением предок/потомок. Windows также поддерживает совершенно другое понятие владения. Каждое окно имеет поле в своей структуре данных, которое содержит логический номер окна, которое владеет этим окном. В отличии от отношения предок/потомок, отношение владения окна является однонаправленным. Окну известен логический номер его окна-владельца, но оно не знает логических номеров окон, которыми оно владеет.

Владелец окна - это окно, которое получает уведомления для окна, которым оно владеет. Например, когда вы создаете окно меню WS_POPUP с помощью функции TrackPopupMenu(), вы задаете владельца окна. Владелец окна получает сообщение WM_COMMAND, порождаемое при выборе пункта меню. Важно отметить, что в общем случае родительское окно и владелец окна совершенно различны. Отношение предок/потомок устанавливает, где в иерархии окон находится окно, тогда как владелец окна определяет, какие окна получают уведомления, предназначенные для окон, которыми они владеют.

Особенность вышеприведенного правила относится и к окнам WS_CHILD. Для окон WS_CHILD владелец HWND в структуре WND дочернего окна равен нулю, и вместо него уведомительные сообщения посылаются родительскому окну. Например, кнопка в окне диалога является потомком главного диалогового окна. Когда вы нажимаете кнопку, окно кнопки уведомляет об этом событии своего предка, т.е. главное диалоговое окно. Вы можете считать, что для ws_child-okhb логический номер hWndOwner — то же самое, что и hWndParenfc, хотя на самом деле они различны. В Presentati

on Manager нет необходимости в битах WS_CHILD или РWS_POPUP. Заполняется как поле hWndPa-rent, так и поле hWndOwner. Это полностью определяет, кто получает уведомительные сообщения потомка, а также положение окна в иерархии. В Presentation Manager поля hWndParent и hWndOw-ner обычно содержат одно и то же значение HWND.

Кроме посылки уведомлений своему владельцу, окно, которым владеют, также всегда расположено впереди окна-владельца. Если окно превращено в пиктограмму, то же происходит и с окнами, которыми оно владеет. Если окно-владелец уничтожается, тто окна, которыми оно владеет, также уничтожаются. Так как окно не следит за окнами, которыми оно владеет, нужно просматривать списки указателей предок/сосед и сравнивать владельца каждого окна с HWND окна, которое уничтожается.

Во всем этом немного странно то, что Windows не делает отношение владения очень явным. Хотя в документации SDK кратко рассматривается отношение владения, вам довольно трудно увидеть, в каких местах отношение владения отличается от отношения предок/потомок. В Presentation Manager OS/2 при создании окна вы задаете и родительское окно, и окно-владелец. В Windows вы задаете только предка.

Если функции CreateWindow() передается только HWND родителя, как тогда вам описать окно владельца в Windows? Одним из параметров функции CreateWindow() является битовая маска стиля. Если стиль окна WS_CHILD, параметр hWndParent интерпретируется как родительское окно. Однако, если вы задаете WS_OVERLAPPED или WS_POPUP, параметр hWndParent в действительность используется как владелец HWND, что позднее проясняется в некотором псевдокоде. Родительским окном для окон WS_OVERLAPPED или WS_POPUP всегда является HWND desktop-окна (HWndDes

ktop).

 



2019-07-03 216 Обсуждений (0)
Каркасное Windows -приложение на ассемблере 0.00 из 5.00 0 оценок









Обсуждение в статье: Каркасное Windows -приложение на ассемблере

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной...
Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (216)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.013 сек.)