乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      消息機(jī)制、子窗口和父窗口的消息傳遞

       喜歡站在山上 2021-01-25

      1. 什么是窗口       

        MSDN: In a graphical Win32-based application, a window is a rectangular area of the screen where the application displays output and receives input from the user. Therefore, one of the first tasks of a graphical Win32-based application is to create a window.       
        大意:窗口就是一個(gè)矩形區(qū)域,應(yīng)用程序可以用它來顯示輸出,或者從user來獲得輸入(鍵盤鼠標(biāo))。在windows中,“一切皆為窗口”。雖然不是很貼切,但是說明了窗口的普遍性和其重要性。比如,你現(xiàn)在看到的QQ聊天窗口,就是由多個(gè)窗口組成的!

        Windows程序是由一系列的窗口構(gòu)成的,每個(gè)窗口都有自己的窗口過程。


      2. 什么是消息       

      MSDN: A data packet used for communicating information or a request. Messages can be passed between the operating system and an application, different applications, threads within an application, and windows within an application.       
        大意:消息就是一組數(shù)據(jù)包(結(jié)構(gòu)體),用于傳遞信息。消息可以在操作系統(tǒng)和一個(gè)進(jìn)程之間傳遞,也可以在兩個(gè)不同的進(jìn)程間傳遞,也可以在同一個(gè)進(jìn)程的不同線程間傳遞或同一個(gè)進(jìn)程的不同窗口間傳遞。 比如,你在QQ聊天窗口中點(diǎn)一下鼠標(biāo),打字等,都會產(chǎn)生消息。在代碼中消息是以消息結(jié)構(gòu)體MSG來保存的,里面的成員包括處理該消息的窗口句柄,消息代碼,消息產(chǎn)生的時(shí)間和光標(biāo)的位置等。   

      消息分類:

      <1>.隊(duì)列消息和非隊(duì)列消息:從消息的發(fā)送途徑上看,消息分兩種:隊(duì)列消息和非隊(duì)列消息。 隊(duì)列消息送到系統(tǒng)消息隊(duì)列,然后到線程消息隊(duì)列;非隊(duì)列消息直接送給目的窗口過程。這里,對消息隊(duì)列闡述如下:

        Windows維護(hù)一個(gè)系統(tǒng)消息隊(duì)列(System message queue),每個(gè)GUI線程有一個(gè)線程消息隊(duì)列(Thread message queue)。鼠標(biāo)、鍵盤事件由鼠標(biāo)或鍵盤驅(qū)動(dòng)程序轉(zhuǎn)換成輸入消息并把消息放進(jìn)系統(tǒng)消息隊(duì)列,例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。Windows每次從系統(tǒng)消息隊(duì)列移走一個(gè)消息,確定它是送給哪個(gè)窗口的和這個(gè)窗口是由哪個(gè)線程創(chuàng)建的,然后,把它放進(jìn)窗口創(chuàng)建線程的線程消息隊(duì)列。線程消息隊(duì)列接收送給該線程所創(chuàng)建窗口的消息。線程從消息隊(duì)列取出消息,通過Windows把它送給適當(dāng)?shù)拇翱谶^程來處理。
        除了鍵盤、鼠標(biāo)消息以外,隊(duì)列消息還有WM_PAINT、WM_TIMER和WM_QUIT。這些隊(duì)列消息以外的絕大多數(shù)消息是非隊(duì)列消息。

      <2>.系統(tǒng)消息和應(yīng)用程序消息: 從消息的來源來看,可以分為:系統(tǒng)定義的消息和應(yīng)用程序定義的消息。(控件改變時(shí)自己也會向系統(tǒng)發(fā)送消息,如invalidate

        系統(tǒng)消息ID的范圍是從0到WM_USER-1,或0X80000到0XBFFFF;應(yīng)用程序消息從WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范圍的消息由應(yīng)用程序自己使用;0XC000到0XFFFF范圍的消息用來和其他應(yīng)用程序通信,為了ID的唯一性,使用::RegisterWindowMessage來得到該范圍的消息ID。

      <3>.窗口消息,命令消息,控件通知消息:根據(jù)處理過程的不同,可以分為三類:窗口消息,命令消息,控件通知消息。
         (1).窗口消息
          一般以WM_開頭,如WM_CREATE, WM_SIZE, WM_MOUSEMOVE等標(biāo)準(zhǔn)的Windows消息, 用于窗口相關(guān)的事件通知,窗口消息將由系統(tǒng)分配到該窗口的窗口過程處理。
         (2).命令消息 (WM_COMMAND)
          一種特殊的窗口消息,它從一個(gè)窗口發(fā)送到另一個(gè)窗口以處理來自用戶的請求,通常是從子窗口發(fā)送到父窗口,例如,點(diǎn)擊按鈕時(shí),按鈕的父窗口會收到WM_COMMAND消息,用以通知父窗口按鈕被點(diǎn)擊,經(jīng)測試:子窗口向父窗口發(fā)送WM_COMMAND消息,或者稱為父窗口會收到WM_COMMAND消息,操作系統(tǒng)并不是通過將WM_COMMAND消息放入到父窗口的消息隊(duì)列中去,而是直接調(diào)用了父窗口的窗口過程,以 WM_COMMAND 為消息標(biāo)識參數(shù)(UINT uMsg),實(shí)現(xiàn)這個(gè)功能的API函數(shù)正是: LRESULT DispatchMessage(const MSG *lpmsg);
         (3).控件通知消息
          WM_NOTIFY消息,當(dāng)用戶與控件交互(Edit, Button...)時(shí),通知消息會從控件窗口發(fā)送到父窗口,這種消息的目的不是為了處理用戶命令,而是為了讓父窗 口能夠適時(shí)的改變控件。

      3. 什么是窗口過程函數(shù)   

        我們鼠標(biāo)、鍵盤消息是在窗口上產(chǎn)生的,windows會把消息傳給該窗口所屬線程的消息隊(duì)列中。然后這個(gè)消息在某個(gè)時(shí)間被這個(gè)窗口對應(yīng)的處理函數(shù)來“搞定”。       
      這個(gè)和窗口綁定的“處理消息的函數(shù)”就是“窗口過程函數(shù)”。       
        一般的,一個(gè)窗口類綁定一個(gè)窗口過程函數(shù)。       


      4. 怎么創(chuàng)建窗口       

      首先,對于windows系統(tǒng)來講,不管你是C#還是C++還是JAVA,要?jiǎng)?chuàng)建一個(gè)標(biāo)準(zhǔn)的窗口,都是調(diào)用相同的API的~       
      只是在VC、C# .NET或用JAVA開發(fā)windows時(shí),開發(fā)工具都幫你把創(chuàng)建窗口“通用的部分”封裝了起來,你是看不到的。       
      在我們C#的代碼中,在Main函數(shù)里已經(jīng)給我們創(chuàng)建好了第一個(gè)窗口Fomr1。為我們免去了N多初始化的麻煩,但是我們也就不知道窗口是怎么被創(chuàng)造出來的了。       
      因此,這里的示例代碼使用的是最原始,最明顯的方法來創(chuàng)建一個(gè)窗口,顯示出來并處理你發(fā)出的消息。我們用C語言來調(diào)用API創(chuàng)建窗口。       
      創(chuàng)建窗口的4個(gè)步驟:       
      1) 初始化窗口類(實(shí)際上是一個(gè)結(jié)構(gòu)體)       
      WNDCLASS wndclass;       
      2) 注冊這個(gè)類       
      RegisterClass(……);       
      3) 創(chuàng)建窗口       
      hwnd = CreateWindow(……);       
      4) 顯示       
      ShowWindow(hwnd, iCmdShow);       
      精簡后的創(chuàng)建窗口程序主干:       
      WinMain(……)       
      {       
      ……       
      HWND hwnd;//用來存放窗口句柄       
      MSG msg;//用來存放消息的結(jié)構(gòu)體       
      WNDCLASS wndclass;// 1)窗口結(jié)構(gòu)體    
      RegisterClass(……);// 2)注冊窗口類     
      hwnd = CreateWindow(……);// 3)創(chuàng)建窗口    
      ShowWindow(hwnd, iCmdShow);// 4)顯示       
      UpdateWindow(hwnd);     
      //下面是消息循環(huán)       
      while(GetMessage(&msg, NULL, 0, 0))       
      {       
      TranslateMessage(&msg);       
      DispatchMessage(&msg);       
      }       
      return msg.wParam;       
      }       

      說明:       
      1) WNDCLASS wndclass;       
      這個(gè)結(jié)構(gòu)體里存放了窗口的各種初始數(shù)據(jù)。如窗體類的風(fēng)格,窗體上顯示的圖標(biāo),鼠標(biāo)的圖標(biāo)等。       
      2) RegisterClass(……);       
      調(diào)用該函數(shù)通知系統(tǒng)被注冊類的窗口的消息,windows為后面創(chuàng)建窗口準(zhǔn)備一系列資源。       
      3) hwnd = CreateWindow(……);       
      調(diào)用該函數(shù)創(chuàng)建較迭的、彈出的或子窗口。它指定窗口類、窗口標(biāo)題、窗口風(fēng)格和窗口的初始大小與位置等。       
      創(chuàng)建出來的窗口以屬于“活動(dòng)”狀態(tài),已經(jīng)開始進(jìn)行消息處理。只是沒有被“顯示”出來。       
      4) ShowWindow(hwnd, iCmdShow);       
      該函數(shù)用來設(shè)置指定窗口的“顯示狀態(tài)”,如大小、位置、是否隱藏等。

      5. 消息是怎么傳遞并處理的           
      消息(Message)在窗口中產(chǎn)生后,系統(tǒng)把它放入到該窗口所屬線程的消息隊(duì)列中,等待處理。       
      線程將隊(duì)列中的消息取得后,在翻譯后,將它“投放”到相應(yīng)的窗口過程函數(shù)中進(jìn)行處理。       

      消息處理機(jī)制的核心代碼:       
      while(GetMessage(&msg, NULL, 0, 0))       
      {       
      TranslateMessage(&msg);       
      DispatchMessage(&msg);       
      }       
      根據(jù)MSDN,上面幾個(gè)函數(shù)的作用:       
        1.GetMessage只獲取自己所屬線程的消息隊(duì)列中的消息,包括windows消息和通過PostThreadMessage發(fā)送的線程消息。       
        2.TranslateMessage是為了將虛擬鍵消息“翻譯”成字符消息,然后把字符消息放回到線程的消息隊(duì)列中,在下一次被GetMessage取得。(具體內(nèi)容見MSDN)        
        3.DispatchMessage的作用是將從GetMessage獲得的消息分發(fā)給相應(yīng)的窗口處理函數(shù)(WndProc),然后窗口過程函數(shù)對消息進(jìn)行處理。       

      上面代碼中使用while循環(huán)的意義是:循環(huán)是應(yīng)用程序能夠持續(xù)存在的根本原因。如果循環(huán)退出,則應(yīng)用程序就結(jié)束了。



      消息是根據(jù)窗口進(jìn)行分發(fā)的,而不考慮該窗口的從屬關(guān)系。也就是說在子窗口中產(chǎn)生的消息只在子窗口函數(shù)中處理,處理完后不會再把消息傳遞給父窗口(除非你自己做反射)。       
      對窗口、線程、消息的關(guān)系總結(jié):       
      1.每一個(gè)窗口都是屬于某一個(gè)線程的,注意是線程       
      2.每一個(gè)窗口都“綁定”了一個(gè)“窗口函數(shù)”!也就是在每個(gè)窗口上產(chǎn)生的消息,會發(fā)往對應(yīng)的函數(shù)來處理!
      3.每一個(gè)線程都有一個(gè)屬于自己的“消息隊(duì)列”    
      圖示:   


             

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多