Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

398 lines
8.7 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  2. /*---------------------------------------------------------
  3. Filename: window.cpp
  4. Written By: B.Rajeev
  5. ----------------------------------------------------------*/
  6. #include "precomp.h"
  7. #include "common.h"
  8. #include "timer.h"
  9. #include "window.h"
  10. extern HINSTANCE g_hInst ;
  11. WindowMapping Window::mapping;
  12. CriticalSection Window::window_CriticalSection;
  13. UINT Window :: g_TimerMessage = SNMP_WM_TIMER ;
  14. UINT Window :: g_SendErrorEvent = SEND_ERROR_EVENT ;
  15. UINT Window :: g_OperationCompletedEvent = OPERATION_COMPLETED_EVENT ;
  16. UINT Window :: g_MessageArrivalEvent = MESSAGE_ARRIVAL_EVENT ;
  17. UINT Window :: g_SentFrameEvent = SENT_FRAME_EVENT ;
  18. UINT Window :: g_NullEventId = NULL_EVENT_ID ;
  19. UINT Window :: g_DeleteSessionEvent = DELETE_SESSION_EVENT ;
  20. BOOL WaitPostMessage (
  21. HWND window ,
  22. UINT user_msg_id,
  23. WPARAM wParam,
  24. LPARAM lParam
  25. )
  26. {
  27. BOOL status = FALSE ;
  28. while ( ! status )
  29. {
  30. status = :: PostMessage ( window , user_msg_id, wParam, lParam ) ;
  31. if ( status )
  32. {
  33. return status ;
  34. }
  35. DWORD lastError = GetLastError () ;
  36. if ( lastError != E_OUTOFMEMORY )
  37. {
  38. TerminateProcess ( GetCurrentProcess () , lastError ) ;
  39. }
  40. }
  41. return FALSE ;
  42. }
  43. Window::Window (
  44. char *templateCode,
  45. BOOL display
  46. ) : window_handle ( NULL )
  47. {
  48. // is invalid
  49. is_valid = FALSE;
  50. // initialize the window
  51. Initialize (
  52. templateCode,
  53. HandleGlobalEvent,
  54. display
  55. ) ;
  56. // if handle is null, return
  57. if ( window_handle == NULL )
  58. return;
  59. is_valid = TRUE;
  60. }
  61. LONG_PTR CALLBACK WindowsMainProc (
  62. HWND hWnd,
  63. UINT message ,
  64. WPARAM wParam ,
  65. LPARAM lParam
  66. )
  67. {
  68. return DefWindowProc(hWnd, message, wParam, lParam);
  69. }
  70. BOOL Window::CreateCriticalSection ()
  71. {
  72. return TRUE ;
  73. }
  74. void Window::DestroyCriticalSection()
  75. {
  76. }
  77. void Window::Initialize (
  78. char *templateCode,
  79. WNDPROC EventHandler,
  80. BOOL display
  81. )
  82. {
  83. WNDCLASS wc ;
  84. wc.style = CS_HREDRAW | CS_VREDRAW ;
  85. wc.lpfnWndProc = EventHandler ;
  86. wc.cbClsExtra = 0 ;
  87. wc.cbWndExtra = 0 ;
  88. wc.hInstance = g_hInst ;
  89. wc.hIcon = LoadIcon(NULL, IDI_HAND) ;
  90. wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  91. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  92. wc.lpszMenuName = NULL ;
  93. wc.lpszClassName = L"templateCode" ;
  94. ATOM winClass = RegisterClass ( &wc ) ;
  95. if ( ! winClass )
  96. {
  97. DWORD t_GetLastError = GetLastError () ;
  98. DebugMacro4(
  99. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
  100. __FILE__,__LINE__,
  101. L"Window::Initialise: Error = %lx\n" , t_GetLastError
  102. ) ;
  103. )
  104. }
  105. window_handle = CreateWindow (
  106. L"templateCode" , // see RegisterClass() call
  107. L"templateCode" , // text for window title bar
  108. WS_OVERLAPPEDWINDOW , // window style
  109. CW_USEDEFAULT , // default horizontal position
  110. CW_USEDEFAULT , // default vertical position
  111. CW_USEDEFAULT , // default width
  112. CW_USEDEFAULT , // default height
  113. NULL , // overlapped windows have no parent
  114. NULL , // use the window class menu
  115. g_hInst, // instance (0 is used)
  116. NULL // pointer not needed
  117. ) ;
  118. if ( window_handle == NULL )
  119. return;
  120. // obtain lock
  121. CriticalSectionLock lock(window_CriticalSection);
  122. // if cannot obtain lock, destroy the window
  123. // since the window cannot be registered, future messages to
  124. // it cannot be passed to it for processing
  125. if ( !lock.GetLock(INFINITE) )
  126. {
  127. DestroyWindow(window_handle);
  128. window_handle = NULL;
  129. return;
  130. }
  131. // register the window with the mapping
  132. // (HWND,event_handler)
  133. try
  134. {
  135. mapping[window_handle] = this;
  136. }
  137. catch ( Heap_Exception e_He )
  138. {
  139. DestroyWindow(window_handle);
  140. window_handle = NULL;
  141. return ;
  142. }
  143. // release lock
  144. lock.UnLock();
  145. if ( display == TRUE )
  146. {
  147. ShowWindow ( window_handle , SW_SHOW ) ;
  148. }
  149. }
  150. BOOL Window::InitializeStaticComponents()
  151. {
  152. return CreateCriticalSection();
  153. }
  154. void Window::DestroyStaticComponents()
  155. {
  156. DestroyCriticalSection();
  157. }
  158. // it determines the corresponding EventHandler and calls it
  159. // with the appropriate parameters
  160. LONG_PTR CALLBACK Window::HandleGlobalEvent (
  161. HWND hWnd ,
  162. UINT message ,
  163. WPARAM wParam ,
  164. LPARAM lParam
  165. )
  166. {
  167. LONG_PTR rc = 0 ;
  168. // send timer events to the Timer
  169. if ( message == WM_TIMER )
  170. {
  171. #if 1
  172. UINT timerId = ( UINT ) wParam ;
  173. SnmpTimerObject *timerObject ;
  174. CriticalSectionLock session_lock(Timer::timer_CriticalSection);
  175. if ( !session_lock.GetLock(INFINITE) )
  176. throw GeneralException ( Snmp_Error , Snmp_Local_Error,__FILE__,__LINE__ ) ;
  177. if ( SnmpTimerObject :: timerMap.Lookup ( timerId , timerObject ) )
  178. {
  179. SnmpTimerObject :: TimerNotification ( timerObject->GetHWnd () , timerId ) ;
  180. }
  181. else
  182. {
  183. }
  184. #else
  185. UINT timerId = ( UINT ) wParam ;
  186. SnmpTimerObject *timerObject ;
  187. CriticalSectionLock session_lock(Timer::timer_CriticalSection);
  188. if ( !session_lock.GetLock(INFINITE) )
  189. throw GeneralException ( Snmp_Error , Snmp_Local_Error,__FILE__,__LINE__ ) ;
  190. if ( SnmpTimerObject :: timerMap.Lookup ( timerId , timerObject ) )
  191. {
  192. Timer::HandleGlobalEvent(timerObject->GetHWnd (), Timer :: g_SnmpWmTimer, timerId, lParam);
  193. }
  194. else
  195. {
  196. }
  197. #endif
  198. return rc ;
  199. }
  200. if ( message == Timer :: g_SnmpWmTimer )
  201. {
  202. Timer::HandleGlobalEvent(
  203. hWnd,
  204. message,
  205. wParam,
  206. (DWORD)lParam
  207. );
  208. return rc;
  209. }
  210. Window *window;
  211. // obtain lock
  212. CriticalSectionLock lock(window_CriticalSection);
  213. // if cannot obtain lock, print a debug error message
  214. // and return
  215. if ( !lock.GetLock(INFINITE) )
  216. {
  217. DebugMacro4(
  218. SnmpDebugLog :: s_SnmpDebugLog->WriteFileAndLine (
  219. __FILE__,__LINE__,
  220. L"Window::HandleGlobalEvent: ignoring window message (unable to obtain lock)\n"
  221. ) ;
  222. )
  223. return rc;
  224. }
  225. BOOL found = mapping.Lookup(hWnd, window);
  226. // release lock
  227. lock.UnLock();
  228. // if no such window, return
  229. if ( !found )
  230. return DefWindowProc(hWnd, message, wParam, lParam);
  231. // let the window handle the event
  232. return window->HandleEvent(hWnd, message, wParam, lParam);
  233. }
  234. // calls the default handler
  235. // a deriving class may override this, but
  236. // must call this method explicitly for default
  237. // case handling
  238. LONG_PTR Window::HandleEvent (
  239. HWND hWnd ,
  240. UINT message ,
  241. WPARAM wParam ,
  242. LPARAM lParam
  243. )
  244. {
  245. return DefWindowProc ( hWnd , message , wParam , lParam );
  246. }
  247. bool WaitLock ( CriticalSectionLock &a_Lock , BOOL a_WaitCritical = TRUE )
  248. {
  249. SetStructuredExceptionHandler t_StructuredException ;
  250. BOOL t_Do ;
  251. do
  252. {
  253. try
  254. {
  255. a_Lock.GetLock(INFINITE) ;
  256. return true ;
  257. }
  258. catch ( Structured_Exception & t_StructuredException )
  259. {
  260. #ifdef DBG
  261. OutputDebugString ( L"CriticalSection exception" ) ;
  262. #endif
  263. t_Do = a_WaitCritical ;
  264. if ( t_Do )
  265. {
  266. Sleep ( 1000 ) ;
  267. }
  268. if ( t_StructuredException.GetSENumber () == STATUS_NO_MEMORY )
  269. {
  270. }
  271. else
  272. {
  273. return false ;
  274. }
  275. }
  276. catch ( ... )
  277. {
  278. return false ;
  279. }
  280. }
  281. while ( t_Do ) ;
  282. return true ;
  283. }
  284. Window::~Window(void)
  285. {
  286. if ( window_handle != NULL )
  287. {
  288. // obtain lock
  289. CriticalSectionLock lock(window_CriticalSection);
  290. if ( WaitLock ( lock ) )
  291. {
  292. mapping.RemoveKey(window_handle);
  293. }
  294. else
  295. {
  296. throw GeneralException ( Snmp_Error , Snmp_Local_Error,__FILE__,__LINE__ ) ;
  297. }
  298. // release lock
  299. lock.UnLock();
  300. DestroyWindow(window_handle);
  301. UnregisterClass ( L"templateCode" , 0 ) ;
  302. }
  303. }
  304. BOOL Window::PostMessage(
  305. UINT user_msg_id,
  306. WPARAM wParam,
  307. LPARAM lParam
  308. )
  309. {
  310. return WaitPostMessage(GetWindowHandle(), user_msg_id, wParam, lParam);
  311. }