win32 013 繪製窗口打開鏈接

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 羅雲彬, http://asm.yeah.net
; change by 小甲魚, http://www.fishc.com
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; FirstWindow.asm
; 窗口程序的模板代碼
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令進行編譯和鏈接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定義
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include shell32.inc
includelib shell32.lib


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 數據段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?


.const
szClassName db'MyClass',0
szCaptionMain db'My first Window !',0
szText db 'Welcome to fishc.com!',0
szOpen db 'open', 0
szURL db 'http://www.fishc.com',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代碼段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口過程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain procuses ebx edi esi hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @hDc
local @hBrush

mov eax,uMsg
;********************************************************************
.if eax ==WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax


invoke GetClientRect,hWnd,addr @stRect
invoke DrawText,@hDc,addr szText,-1,\
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER


invoke EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;********************************************************************
.elseif eax == WM_NCPAINT
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
invoke ShellExecute, NULL, offset szOpen,\
offset szURL, NULL, NULL, SW_SHOWNORMAL
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret


_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG


invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass 
;********************************************************************
; 註冊窗口類
;********************************************************************
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance                          ; 注意這種拷貝的方法,以後會常碰到的
pop @stWndClass.hInstance  ; 思考:爲什麼不用mov @stWndClass.hInstance, hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立並顯示窗口
;********************************************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,600,400,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循環
;********************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret


_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start

 

 

 

 

 

WM_NCPAINT

        當窗體框架(非客戶區)要被重畫時,WM_NCPAINT消息產生

         窗體可用一個WindowProc函數接收這個消息

      LRESULT CALLBACK WindowProc(

              HWND hwnd,      // 窗體句柄

               UINT uMsg,      // WM_NCPAINT

               WPARAMwParam,  //處理窗體更新區域 (HRGN)

               LPARAMlParam    //不用

);

       參數

           wParam

處理窗體更新區域,對窗體來說缺省更新的部分區域是框架。當wParam設爲1時,整個窗體將得到更新。

       返回值

              如果應用這個消息就返回零

       附言:

              DefWindowProc函數畫窗體框架,可以攔截這條WM_NCPAINT消息

                            並畫自己特有風格的窗體框架。剪切區域總是直角矩形,即使窗體的框架

                            被改變。

                            wParam可以傳給GetDCEx函數。看下面例子

       case WM_NCPAINT:

        {

               HDC hdc;

                        hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);

                       // 進入設備場景畫

               ReleaseDC(hwnd, hdc);

}

 

 

 

WinAPI: ShellExecute - 打開外部程序或文件

ShellExecute(
  hWnd: HWND;        {指定父窗口句柄}
  Operation: PChar;  {指定動作, 譬如: open、print}
  FileName: PChar;   {指定要打開的文件或程序}
  Parameters: PChar; {給要打開的程序指定參數; 如果打開的是文件這裏應該是 nil}
  Directory: PChar;  {缺省目錄}
  ShowCmd: Integer   {打開選項}
): HINST;            {執行成功會返回應用程序句柄; 如果這個值 <= 32, 表示執行錯誤}

//返回值可能的錯誤有:
                       = 0   {內存不足}
ERROR_FILE_NOT_FOUND   = 2{文件名錯誤}
ERROR_PATH_NOT_FOUND   = 3{路徑名錯誤}
ERROR_BAD_FORMAT       = 11; {EXE 文件無效}
SE_ERR_SHARE           = 26; {發生共享錯誤}
SE_ERR_ASSOCINCOMPLETE = 27; {文件名不完全或無效}
SE_ERR_DDETIMEOUT      = 28; {超時}
SE_ERR_DDEFAIL         = 29; {DDE 事務失敗}
SE_ERR_DDEBUSY         = 30; {正在處理其他 DDE 事務而不能完成該 DDE 事務}
SE_ERR_NOASSOC         = 31; {沒有相關聯的應用程序}

//ShowCmd 參數可選值:
SW_HIDE            = 0{隱藏}
SW_SHOWNORMAL      = 1{用最近的大小和位置顯示, 激活}
SW_NORMAL          = 1{同 SW_SHOWNORMAL}
SW_SHOWMINIMIZED   = 2{最小化, 激活}
SW_SHOWMAXIMIZED   = 3{最大化, 激活}
SW_MAXIMIZE        = 3{同 SW_SHOWMAXIMIZED}
SW_SHOWNOACTIVATE  = 4{用最近的大小和位置顯示, 不激活}
SW_SHOW            = 5{同 SW_SHOWNORMAL}
SW_MINIMIZE        = 6{最小化, 不激活}
SW_SHOWMINNOACTIVE = 7{同 SW_MINIMIZE}
SW_SHOWNA          = 8{同 SW_SHOWNOACTIVATE}
SW_RESTORE         = 9{同 SW_SHOWNORMAL}
SW_SHOWDEFAULT     = 10; {同 SW_SHOWNORMAL}
SW_MAX             = 10; {同 SW_SHOWNORMAL}
//舉例說明更多問題(別忘了 uses ShellAPI;):

{譬如用記事本打開一個文件}
begin
  ShellExecute(Handle, 'open', 'notepad.exe', 'C:\WINDOWS\SchedLgU.Txt', nil, SW_SHOWNORMAL);
end;
{第一個參數是用來當作錯誤提示窗口的父窗口的, 不能是 nil, 可以是 0(也就是桌面窗口)}
begin
  ShellExecute(0, 'open', 'notepad.exe', 'C:\WINDOWS\SchedLgU.Txt', nil, SW_SHOWNORMAL);
end;
{第二個參數如果是 nil, 也會默認位 open}
begin
  ShellExecute(0, nil, 'notepad.exe', 'C:\WINDOWS\SchedLgU.Txt', nil, SW_SHOWNORMAL);
end;
{文件路徑可以放在參數五}
begin
  ShellExecute(0, nil, 'notepad.exe', 'SchedLgU.Txt', 'C:\WINDOWS', SW_SHOWNORMAL);
end;
{把參數三直接指定爲要打開的文件, 文件將用對應默認程序打開; 次數參數四應爲 nil}
begin
  ShellExecute(0, nil, 'SchedLgU.Txt', nil, 'C:\WINDOWS', SW_SHOWNORMAL);
end;
{如果文件在: 程序目錄/當前目錄/System32/Windows/PATH環境變量中, 參數五也可以 nil}
begin
  ShellExecute(0, nil, 'SchedLgU.Txt', nil, nil, SW_SHOWNORMAL);
end;
{如果參數三是個文件, 可以用參數二命令打印}
begin
  ShellExecute(0, 'print', 'SchedLgU.Txt', nil, nil, 1);
end;
{用 IE 打開網頁}
begin
  ShellExecute(Handle, 'open', 'IExplore.EXE', 'about:blank', nil, SW_SHOWNORMAL);
end;
{用火狐打開網頁}
begin
  ShellExecute(Handle, 'open', 'firefox.exe', 'about:blank', nil, SW_SHOWNORMAL); 
end;
{用默認瀏覽器打開網頁}
begin
  ShellExecute(Handle, 'open', 'Explorer.exe', 'about:blank', nil, SW_SHOWNORMAL);
end;
{還是用默認瀏覽器打開網頁}
begin
  ShellExecute(0, nil, 'http://del.cnblogs.com', nil, nil, 1);
end;

 

                     


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章