Вопрос 2. Механизм сообщений в ОС Windows : назначение, принципы функционирования, структура сообщения, программные приемы обработки сообщений. Пример программы, выводящей в окне слово «ТЕСТ - ОК» при щелчке правой клавиши мыши, если нажаты на клавиатуре


Добавил:DMT
Дата создания:30 декабря 2007, 18:55
Дата обновления:9 января 2008, 23:29
Просмотров:13896 последний позавчера, 17:02
Комментариев: 1

Вопрос 2. Механизм сообщений в ОС Windows : назначение, принципы функционирования, структура сообщения, программные приемы обработки сообщений. Пример программы, выводящей в окне слово «ТЕСТ – ОК» при щелчке правой клавиши мыши, если нажаты на клавиатуре клавиши Ctrl + Shift + Alt .

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

Хотя сообщения передаются приложениям, они адресованы окнам, представляющим некую абстрактную сущность, через которую взаимодействуют пользо­ватель и приложение.

Передача сообщений - это способ, при помощи которого в Windows организован обмен информацией между отдельными подсистемами, приложениями или между отдельными модулями одного и того же приложения. Каждое Windows-приложение построено на основе цикла сообщений. Цикл сообщении повторно вызывает функции GetMessage или PeekMessage и получает сообщения, которые затем передает оконной процедуре через функцию DispatchMessage .

Сообщение представляет собой структуру данных:

typedef struct tagMSG { HWND hwnd ; //адресат (идентификатор получателя) сообщения UINT message ; //уникальный код сообщения WPARAM wParam ; //содержимое сообщения wParam LPARAM lParam ; //содержимое сообщения lParam DWORD time ; //время отправления POINT pt ; //информация о координатах } MSGMSG ;

 

Сообщения могут быть отправлены или посланы приложению. Отправленные сообщения помещаются в очередь сообщений, из которой функции GetMessage или PeekMessage получают эти сообщения. В п po тивоположность этому посылка сообщения означает немедленный вызов оконной процедуры, обходя очередь сообщений и цикл сообщений.

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

Windows содержит в себе системную очередь сообщений, куда последние могут поступать от драйверов устройств ввода/вывода или от приложений, а также несколько очередей сообщений для каждого приложения.

Идентификаторы сообщений задаются в заголовочных файлах Windows . Сообщения представляются каждым простым событием, каждое простое действие посыла­ется окну для обработки. Вместо обработки всех возможных сообщений приложение имеет свободу выбора; необработанные сообщения передаются в функции обработки сообщений операционной системы по умолчанию.

Уникальный идентификатор сообщения можно получить вызовом функции RegisterWindowMessage . Использование собственных типов сообщений позволяет частям приложения связываться между собой; разные приложения также могут обмениваться информацией таким способом.

По мере генерации приложениями, сообщения попадают вначале в общую системную очередь и затем распределяются в очереди отдельных приложений. Действие, выполненное над любым органом управления, приводит к генерации соответствующего сообщения и помещения этого сообщения в очередь приложения. Приложение Windows постоянно анализирует содержимое своей очереди сообщений. Когда в очереди появляется сообщение от какого-либо органа управления, приложение выполняет соответствующее действие. В очередь сообщений приложения Windows заносит сообщение, содержащее идентификатор использованного органа управления. Приложение анализирует очередь сообщений и выполняет обработку сообщений. В Windows используется многоуровневая система сообщений.

Сообщения низкого уровня вырабатываются передаются операционной системе Windows, которая на их основе формирует сообщения более высокого уровня.

Операционная система Windows направляет сообщение от использованного органа управления в очередь того приложения, к которому принадлежит данный орган управления. Каждое приложение занимается обработкой своей очереди сообщений, а Windows заботится о том, чтобы все сообщения попадали в нужную очередь.

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

 

Пример программы, выводящей в окне слово «ТЕСТ – ОК» при щелчке правой клавиши мыши, если нажаты на клавиатуре клавиши Ctrl + Shift + Alt .

Код на C++
  1.  
  2. #include <windows.h>
  3.  
  4. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  5.  
  6. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR
  7. szCmdLine, int iCmdShow)
  8. {
  9. static char szAppName[] = "test";
  10. HWND hwnd;
  11. MSG msg;
  12. WNDCLASS wndclass;
  13. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  14. wndclass.lpfnWndProc = WndProc;
  15. wndclass.cbClsExtra = 0;
  16. wndclass.cbWndExtra = 0;
  17. wndclass.hInstance = hInstance;
  18. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  19. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  20. wndclass.hbrBackground =(HBRUSH) GetStockObject(WHITE_BRUSH);
  21. wndclass.lpszMenuName = NULL;
  22. wndclass.lpszClassName = szAppName;
  23. //регистрируем класс окна
  24. RegisterClass(&wndclass);
  25. //создаем окно
  26. hwnd = CreateWindow
  27. (szAppName,"тест",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
  28. CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
  29. //рисуем окно
  30. ShowWindow(hwnd, iCmdShow);
  31. UpdateWindow(hwnd);
  32. while(GetMessage(&msg, NULL, 0, 0))
  33. {
  34. //добавляет в очередь сообщений сообщение о нажатой клавише
  35.  
  36. TranslateMessage(&msg);
  37. DispatchMessage(&msg);
  38. }
  39. return msg.wParam;
  40. }
  41.  
  42. LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM
  43. lParam)
  44. {
  45. switch(iMsg)
  46. {
  47. case WM_DESTROY:
  48. PostQuitMessage(0);
  49. return 0;
  50. //если нажата правая кнопка мыши
  51. case WM_RBUTTONDOWN:
  52. //и нажаты клавиши ctrl + shift + alt - вывести
  53. сообщение
  54. if (GetKeyState(VK_CONTROL)&&GetKeyState(VK_SHIFT)
  55. &&GetKeyState(VK_MENU))
  56. MessageBox(hwnd, "ТЕСТ - ОК", "ОК", MB_OK);
  57. return 0;
  58. }
  59. return DefWindowProc(hwnd, iMsg, wParam, lParam);
  60. }
  61.  
  62.  
При использовании обязательна ссылка на http://DMTSoft.ru
up

Комментарии для "Вопрос 2. Механизм сообщений в ОС Windows : назначение, принципы функционирования, структура сообщения, программные приемы обработки сообщений. Пример программы, выводящей в окне слово «ТЕСТ - ОК» при щелчке правой клавиши мыши, если нажаты на клавиатуре "


Пользователь: DMT
Сообщений: 123
Статус: Программист
Зарегистрирован:
18 октября 2007, 2:35
Был:13 ноября 2017, 4:54
DMT
smsup
Дата: 1 января 2008, 15:29 Сообщение № 1
Вот собственно программу написал, старалса sm
Код на ASM
  1. ; 1.01.2007 DMT (c)
  2. ; При нажатии на форму левой кнопкой мыши
  3. ; вместе с зажатыми клавишами CTRL+SHIFT+ALT
  4. ; рисуется надпись "ТЕСТ - ОК"
  5. .386
  6. .model flat,stdCall
  7. option casemap :none
  8. WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
  9. Read_key PROTO
  10. include \masm32\include\windows.inc
  11. include \masm32\include\gdi32.inc
  12. includelib \masm32\lib\gdi32.lib
  13. include \masm32\include\masm32.inc
  14. includelib \masm32\lib\masm32.lib
  15. include \masm32\include\kernel32.inc
  16. includelib \masm32\lib\kernel32.lib
  17. include \masm32\include\user32.inc
  18. includelib \masm32\lib\user32.lib
  19. .data
  20. user_msq db 'TECT - ОК',0;
  21. class_name db 'DMTWinClass',0;
  22. app_name db 'DMTWindow _ _ _',0
  23. var1 dd 16700
  24. show_user_msg db 0
  25. keys_d db 255 dup(0),0
  26. .data?
  27. timer_id1 dd ?
  28. timer_id1_ dd ?
  29. h_instance HINSTANCE ?
  30. cmd_line LPSTR ?
  31. rand_int DWORD ?
  32. hwnd HWND ?
  33. .code
  34. start:
  35. invoke GetModuleHandle,NULL
  36. mov h_instance,eax
  37. invoke GetCommandLine
  38. mov cmd_line,eax
  39. invoke WinMain,h_instance,NULL,cmd_line,SW_SHOW
  40. invoke ExitProcess,NULL
  41. WinMain proc hinst:HINSTANCE,prev_inst:HINSTANCE,cmd_l:LPSTR,show:DWORD
  42. LOCAL wc: WNDCLASSEX;
  43. LOCAL msg:MSG;
  44. ;LOCAL hwnd:HWND;
  45. mov wc.cbSize,SIZEOF WNDCLASSEX
  46. mov wc.style,CS_HREDRAW or CS_VREDRAW;
  47. mov wc.lpfnWndProc, OFFSET Obr_msg;
  48. mov wc.cbClsExtra,NULL
  49. mov wc.cbWndExtra,NULL
  50. push hinst
  51. pop wc.hInstance
  52. invoke LoadIcon,NULL,IDI_APPLICATION
  53. mov wc.hIcon,eax
  54. mov wc.hIconSm,eax
  55. invoke LoadCursor,NULL,IDC_ARROW
  56. mov wc.hCursor,eax
  57. mov wc.hbrBackground,COLOR_WINDOW
  58. mov wc.lpszMenuName,NULL
  59. mov wc.lpszClassName,OFFSET class_name
  60. invoke RegisterClassEx, ADDR wc
  61. invoke CreateWindowEx,NULL,\
  62. addr class_name,\
  63. addr app_name,\
  64. WS_OVERLAPPEDWINDOW,\
  65. 100,\
  66. 100,\
  67. 200,\
  68. 200,\
  69. NULL,NULL,hinst,NULL
  70. mov hwnd,eax
  71. invoke ShowWindow,hwnd,show
  72. invoke UpdateWindow,hwnd
  73. .WHILE TRUE
  74. invoke GetMessage,addr msg,NULL,0,0
  75. .BREAK .IF (!eax)
  76. invoke TranslateMessage,addr msg
  77. invoke DispatchMessage,addr msg
  78. .ENDW
  79. mov eax,msg.wParam
  80. xor eax,eax
  81. ret
  82. WinMain endp
  83. Obr_msg proc hw:HWND,msg:UINT,wpar:WPARAM,lpar:LPARAM
  84. LOCAL hdc:HDC;
  85. LOCAL ps:PAINTSTRUCT
  86. .if msg==WM_CREATE
  87. invoke SetTimer,hw,3,100,NULL
  88. mov timer_id1,eax
  89. .elseif msg==WM_DESTROY
  90. invoke PostQuitMessage,NULL
  91. .elseif msg==WM_LBUTTONDOWN
  92. lea ebx,keys_d
  93. add ebx,VK_CONTROL
  94. mov al,byte ptr [ebx]
  95. .if (al==1)
  96. lea ebx,keys_d
  97. add ebx,VK_MENU
  98. mov al,byte ptr [ebx]
  99. .if (al==1)
  100. lea ebx,keys_d
  101. add ebx,VK_SHIFT
  102. mov al,byte ptr [ebx]
  103. .if (al==1)
  104. mov show_user_msg,1
  105. .endif
  106. .endif
  107. .endif
  108. .elseif msg==WM_KEYDOWN
  109. lea eax,keys_d
  110. add eax,wpar
  111. mov BYTE PTR [eax],1
  112. .elseif msg==WM_KEYUP
  113. lea eax,keys_d
  114. add eax,wpar
  115. mov BYTE PTR [eax],0
  116. .ELSEIF msg==WM_PAINT
  117. invoke BeginPaint,hw,addr ps
  118. .if (show_user_msg==1)
  119. mov hdc,eax
  120. invoke TextOut,hdc,0,0,Addr user_msq,SIZEOF user_msq -1
  121. .endif
  122. invoke EndPaint,hw,addr ps
  123. .elseif msg==WM_TIMER
  124. invoke InvalidateRect,hwnd,NULL,TRUE
  125. .ELSE
  126. invoke DefWindowProc,hw,msg,wpar,lpar
  127. ret
  128. .ENDIF
  129. ret
  130. Obr_msg endp
  131. end start
При использовании обязательна ссылка на http://DMTSoft.ru