reactos操作系统实现(161)

NtUserCreateWindowEx函数主要用来创建一个窗口显示。在Win32k.sys里的代码如下:

#001  HWND APIENTRY

#002  NtUserCreateWindowEx(DWORD dwExStyle,

#003                       PUNICODE_STRING UnsafeClassName,

#004                       PUNICODE_STRING UnsafeWindowName,

#005                       DWORD dwStyle,

#006                       LONG x,

#007                       LONG y,

#008                       LONG nWidth,

#009                       LONG nHeight,

#010                       HWND hWndParent,

#011                       HMENU hMenu,

#012                       HINSTANCE hInstance,

#013                       LPVOID lpParam,

#014                       DWORD dwShowMode,

#015                       BOOL bUnicodeWindow,

#016                       DWORD dwUnknown)

#017  {

#018     NTSTATUS Status;

#019     UNICODE_STRING WindowName;

#020     UNICODE_STRING ClassName;

#021     HWND NewWindow;

#022     DECLARE_RETURN(HWND);

#023 

#024     DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)/n", x, y, nWidth, nHeight);

 

用户界面临界区进入。

#025     UserEnterExclusive();

#026 

 

获取窗口类的名称。

#027     /* Get the class name (string or atom) */

#028     Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING));

#029     if (! NT_SUCCESS(Status))

#030     {

#031        SetLastNtError(Status);

#032        RETURN( NULL);

#033     }

#034     if (ClassName.Length != 0)

#035     {

#036        Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);

#037        if (! NT_SUCCESS(Status))

#038        {

#039           SetLastNtError(Status);

#040           RETURN( NULL);

#041        }

#042     }

#043     else if (! IS_ATOM(ClassName.Buffer))

#044     {

#045         SetLastWin32Error(ERROR_INVALID_PARAMETER);

#046         RETURN(NULL);

#047     }

#048 

 

拷贝窗口的名称。

#049     /* safely copy the window name */

#050     if (NULL != UnsafeWindowName)

#051     {

#052        Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName);

#053        if (! NT_SUCCESS(Status))

#054        {

#055           if (! IS_ATOM(ClassName.Buffer))

#056           {

#057              ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);

#058           }

#059           SetLastNtError(Status);

#060           RETURN( NULL);

#061        }

#062     }

#063     else

#064     {

#065        RtlInitUnicodeString(&WindowName, NULL);

#066     }

#067 

 

调用函数co_IntCreateWindowEx来创建窗口。

#068     NewWindow = co_IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight,

#069                                      hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow);

#070 

 

清空窗口名称和窗口类名称的缓冲区。

#071     if (WindowName.Buffer)

#072     {

#073        ExFreePoolWithTag(WindowName.Buffer, TAG_STRING);

#074     }

#075     if (! IS_ATOM(ClassName.Buffer))

#076     {

#077        ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);

#078     }

#079 

 

返回创建的新窗口。

#080     RETURN( NewWindow);

#081 

#082  CLEANUP:

#083     DPRINT("Leave NtUserCreateWindowEx, ret=%i/n",_ret_);

#084     UserLeave();

#085     END_CLEANUP;

#086  }

#087  

posted @ 2009-12-16 23:57  ajuanabc  阅读(236)  评论(0编辑  收藏  举报