• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            面對現實,超越自己
            逆水行舟,不進則退
            posts - 269,comments - 32,trackbacks - 0

            1、MFC對話框顯示BMP圖片

            我們先從簡單的開始吧.先分一個類:


            (一) 非動態顯示圖片(即圖片先通過資源管理器載入,有一個固定ID)

            (二) 動態載入圖片(即只需要在程序中指定圖片的路徑即可載入)

            為方便說明,我們已經建好一個基于對話框的工程,名為Ttest.

            對話框類為CTestDlg

            (一)    非動態載入圖片.

            方法1.先從最簡單的開始,用picture 控件來實現.

            步驟:

            先在資源里Import一張圖片,ID為IDB_BITMAP2

            然后在對話框上添加一個picture控件,右鍵點擊打開屬性,

            將type下拉框選擇BITMAP,緊跟著下面就出現一個Image下拉框,

            拉開就會看到所有已經載入好的圖片,

            選擇你要的圖片.運行程序即可看到.

            方法2.通過背景圖

            同樣如上,先載入一張圖片,ID為IDB_BITMAP2

            TestDlg.h中

            CBrush m_brBk;//在public中定義 

            TestDlg.cpp中

            在初始化函數OnInitDialog()中加入:

            BOOL CTestDlg::OnInitDialog()

            {
                     CDialog::OnInitDialog();

                     CBitmap bmp;

                     bmp.LoadBitmap(IDB_BITMAP2);

                     m_brBk.CreatePatternBrush(&bmp);

                     bmp.DeleteObject();

                     return TRUE;  // return TRUE  unless you set the focus to a control
            }

            在打開類向導,找到WM_CTLCOLOR消息,重載得對應函數OnCtlColor(),添加如下:

            HBRUSH  CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
            {
                     HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

                     if (pWnd == this)
                     {
                            return m_brBk;
                     }

                    return hbr;
            }

            (二)    動態載入圖片.

            方法3 圖像控件(本例用KoDak 圖像編輯控件)

            1.    首先應該保證系統中有這個控件。注意,它不能單獨使用,必須和其他幾個控件(特別是Imgcmn.dll)一同使用。如果沒有,從別的機器上copy過來即可。這幾個文件是Imgadmin.ocx,Imgcmn.dll,Imgedit.ocx,Imgscan.ocx,Imgshl.dll,Imgthumb.ocx,Imgutil.dll,把它們copy到windows/system目錄下,然后用regsvr32.exe將它們分別注冊。 

            2.    打開工程,進入資源管理器,在對話框上單擊右鍵,單擊Insert Activex control… 選擇Kodak圖象編輯控件,大小任意。 

            3.    在對話框上選中該控件,為其添加變量:m_ctrlPicture。。 

            4.    在BOOL CTestDlg::OnInitDialog()添加如下:

            BOOL CTestDlg::OnInitDialog()

            {
                     CDialog::OnInitDialog();

                     m_ctrlPicture.SetImage("aa.jpg");  //保證圖像在工程目錄下,也可以寫絕對路徑

                     m_ctrlPicture.Display();

                     return TRUE;  // return TRUE unless you set the focus to a control

                     // EXCEPTION: OCX Property Pages should return FALSE
            }

            編譯運行就OK了,此種方法的好處就是可能針對多種圖像格式.


            方法4 通過CBitmap,HBITMAP,直接用OnPaint()繪制

            首先在CTestDlg類中聲明一個變量:   CBitmap  m_bmp;

            然后我們在對話框中加入一個picture 標簽,名為IDC_STATIC1

            然后:

            BOOL CDisplayPic::OnInitDialog() 

            {
                   CDialog::OnInitDialog();

                   if( m_bmp.m_hObject != NULL )//判斷

                          m_bmp.DeleteObject();

                   /////////載入圖片

                   HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 

                    "c://aaa.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);

                   if( hbmp == NULL ) 

                       return FALSE;

                   ///////////////////////該斷程序用來取得加載的BMP的信息////////////////////////

                   m_bmp.Attach( hbmp );

                   DIBSECTION ds;

                   BITMAPINFOHEADER &bminfo = ds.dsBmih; 

                   m_bmp.GetObject( sizeof(ds), &ds );

                   int cx=bminfo.biWidth;  //得到圖像寬度

                   int cy=bminfo.biHeight; //得到圖像高度

                  /////////////////// ////////////////////////////////

                  /////////////得到了圖像的寬度和高度后,我們就可以對圖像大小進行適應,即調整控件的大小,讓它正好顯示一張圖片///////////////////////////

                   CRect rect;

                   GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);

                   ScreenToClient(&rect);

                   GetDlgItem(IDC_STATIC1)->MoveWindow(rect.left,rect.top,cx,cy,true);//調整大小

                   return TRUE;  // return TRUE unless you set the focus to a control

                  // EXCEPTION: OCX Property Pages should return FALSE
            }

            圖片加載成功了,標簽大小也適應了,下面就是繪制繪制圖像了,打開類向導,重載WM_PAINT消息

            void CDisplayPic::OnPaint() 

            {
                   //////////////以下三種情況任選一種會是不同效果(只能一種存在)///////////

                   //CPaintDC dc(this);      //若用此句,得到的是對話框的DC,圖片將被繪制在對話框上.

                   CPaintDC dc(GetDlgItem(IDC_STATIC1)); //用此句,得到picture控件的DC,圖像將被繪制在控件上  

                    //若用以下兩句,得到的是屏幕的DC,圖片將被繪制在屏幕上/////////////////////////////////////////////////////
                  
                   //  CDC dc;


                   //  dc.m_hDC=::GetDC(NULL); 

                   CRect rcclient;

                   GetDlgItem(IDC_STATIC1)->GetClientRect(&rcclient);

                   CDC memdc;

                   memdc.CreateCompatibleDC(&dc);  

                   CBitmap bitmap;

                   bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());

                   memdc.SelectObject( &bitmap );

                   CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);

                   CDC maskdc;

                   maskdc.CreateCompatibleDC(&dc);

                   CBitmap maskbitmap;

                   maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);

                   maskdc.SelectObject( &maskbitmap );

                   maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc, 

                    rcclient.left, rcclient.top, SRCCOPY);

                   CBrush brush;

                   brush.CreatePatternBrush(&m_bmp);

                   dc.FillRect(rcclient, &brush);    

                   dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), 

                         &memdc, rcclient.left, rcclient.top,SRCPAINT);

                   brush.DeleteObject();
                   // Do not call CDialog::OnPaint() for painting messages

            }
            以上四種方法唯有KoDak可以支持多種圖像,其它的只支持BMP

            以上轉自:http://blog.csdn.net/cecilia214/article/details/5346302

            以下轉自:http://topic.csdn.net/u/20090410/10/ad7a5afe-c906-45ff-a673-f601e2ec05be.html

            2、MFC對話框顯示JPEG圖片

            放在對話框的OnPaint里

             1 CDC* pDC;   
             2 pDC=GetDC();   
             3 ShowPicture(pDC,"c:\\12.jpg",0,0,200,100);  
             4 
             5 
             6 
             7 #define   HIMETRIC_INCH 2540    
             8 LPPICTURE   gpPicture;   
             9 void CCDMADlg::ShowPicture(CDC *pDC, CString m_strBRoute, int x, int y, int width, int height) 
            10   {    
            11         HANDLE   hFile =CreateFile(m_strBRoute,   GENERIC_READ,   0,   NULL,   OPEN_EXISTING,   0,   NULL);    
            12         _ASSERTE(INVALID_HANDLE_VALUE != hFile);    
            13      
            14         //   取得文件大小    
            15         DWORD   dwFileSize   =   GetFileSize(hFile,   NULL);    
            16         _ASSERTE(-1   !=   dwFileSize);    
            17         LPVOID   pvData   =   NULL;    
            18         //根據文件大小分配內存    
            19         HGLOBAL   hGlobal   =   GlobalAlloc(GMEM_MOVEABLE,   dwFileSize);    
            20         _ASSERTE(NULL   !=   hGlobal);    
            21         pvData   =   GlobalLock(hGlobal);    
            22         _ASSERTE(NULL   !=   pvData);    
            23         DWORD   dwBytesRead   =   0;    
            24         //讀取文件并存入全局內存    
            25         BOOL   bRead   =   ReadFile(hFile,   pvData,   dwFileSize,   &dwBytesRead,   NULL);    
            26         _ASSERTE(FALSE   !=   bRead);    
            27         GlobalUnlock(hGlobal);    
            28         CloseHandle(hFile);    
            29         LPSTREAM   pstm   =   NULL;    
            30         //   通過全局內存創建   IStream*   的指針    
            31         HRESULT   hr   =   CreateStreamOnHGlobal(hGlobal,   TRUE,   &pstm);    
            32         _ASSERTE(SUCCEEDED(hr)   &&   pstm);    
            33         //通過圖形文件創建IPicture   對象    
            34         if   (gpPicture)    
            35               gpPicture->Release();    
            36         hr   =   OleLoadPicture(pstm,   dwFileSize,   FALSE,   IID_IPicture,   (LPVOID   *)&gpPicture);    
            37         _ASSERTE(SUCCEEDED(hr)   &&   gpPicture);    
            38         pstm->Release();    
            39         HDC   hdc;    
            40         hdc=pDC->GetSafeHdc();    
            41         if   (gpPicture)    
            42         {    
            43               //   取得圖片的寬和高    
            44               long   hmWidth;    
            45               long   hmHeight;    
            46               gpPicture->get_Width(&hmWidth);    
            47               gpPicture->get_Height(&hmHeight);    
            48               //寬高轉換為象素    
            49               int   nWidth =   MulDiv(hmWidth,   GetDeviceCaps(hdc,   LOGPIXELSX),   HIMETRIC_INCH);    
            50               int   nHeight =   MulDiv(hmHeight,   GetDeviceCaps(hdc,   LOGPIXELSY),   HIMETRIC_INCH);    
            51               RECT   rc;    
            52               GetClientRect(&rc);/*取得客戶區*/    
            53               gpPicture->Render(hdc,   x,y,   (int)height*hmWidth/hmHeight,height,   0,   hmHeight,   hmWidth,   -hmHeight,   &rc);    
            54               /*顯示圖片*/    
            55         }      
            57   } 

            posted @ 2012-09-10 17:43 王海光 閱讀(14776) | 評論 (0)編輯 收藏

            SetTimer函數用于創建一個計時器,KillTimer函數用于銷毀一個計時器。計時器屬于系統資源,使用完應及時銷毀。

             

              SetTimer的函數原型如下:
            UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc ) ;
              其中
              hWnd是和timer關聯的窗口句柄,此窗口必須為調用SetTimer的線程所有;如果hWnd為NULL,沒有窗口和timer相關聯并且nIDEvent參數被忽略
              nIDEvent是timer的標識,為非零值;如果hWnd為NULL則被忽略;如果hWnd非NULL而且與timer相關聯的窗口已經存在一個為此標識的timer,則此次SetTimer調用將用新的timer代替原來的timer。timer標識和窗口相關,兩個不同的窗口可以擁有nIDEvent相同的tiemr
              uElapse是以毫秒指定的計時間隔值,范圍為1毫秒到4,294,967,295毫秒(將近50天),這個值指示Windows每隔多久時間給程序發送WM_TIMER消息。
              lpTimerFunc是一個回調函數的指針,俗稱TimerFunc;如果lpTimerFunc為NULL,系統將向應用程序隊列發送WM_TIMER消息;如果lpTimerFunc指定了一個值,DefWindowProc將在處理WM_TIMER消息時調用這個lpTimerFunc所指向的回調函數,因此即使使用TimerProc代替處理WM_TIMER也需要向窗口分發消息。

              關于SetTimer的返回值:如果hWnd為NULL,返回值為新建立的timer的ID,如果hWnd非NULL,返回一個非0整數,如果SetTimer調用失敗則返回0

              KillTimer的函數原型為:BOOL KillTimer( HWND hWnd, UINT_PTR uIDEvent ) ; 參數意義同SetTimer。
              關于KillTimer對消息隊列中剩余未處理的WM_TIMER消息的影響,MSDN和Programming Windows上的說法完全相反。MSDN的說法很干脆:The KillTimer function does not remove WM_TIMER messages already posted to the message queue. 而petzold則說 The KillTimer call purges the message queue of any pending WM_TIMER messages. Your program will never receive a stray WM_TIMER message following a KillTimer call.(KillTimer消除消息隊列中任何未處理的WM_TIMER消息,調用KillTimer后你的程序永遠不會收到一條“漂泊游蕩”的WM_TIMER消息)

             

            關于WM_TIMER消息

              wParam為計時器的ID;如果需要設定多個計時器,那么對每個計時器都使用不同的計時器ID。wParam的值將隨傳遞到窗口過程中的WM_TIMER消息的不同而不同。
              lParam為指向TimerProc的指針,如果調用SetTimer時沒有指定TimerProc(參數值為NULL),則lParam為0(即NULL)。
              可以通過在窗口過程中提供一個WM_TIMER case處理這個消息,或者,默認窗口過程會調用SetTimer中指定的TimerProc來處理WM_TIMER消息

             

            使用計時器的三種方法

              如果在程序的整個執行過程中使用計時器,一般在處理WM_CREATE消息時或WinMain中消息循環前調用SetTimer,在處理WM_DESTROY消息時或在WinMain中消息循環后return前調用KillTimer。根據SetTimer中的參數不同,有三種方法使用計時器。

              方法一:調用SetTimer時指定窗口句柄hWnd,nIDEvent中指定計時器ID,將lpTimerFunc置NULL從而不使用TimerProc;在窗口過程中處理WM_TIMER消息調用KillTimer時,使用SetTimer中指定的hWnd和id。最好使用#define定義timer的id,例如:

             

            #define ID_TIMER 1
            SetTimer(hWnd,ID_TIMER,1000,NULL) ;
            KillTimer(hWnd,ID_TIMER) ;

              方法二:調用SetTimer時指定窗口句柄hWnd,nIDEvent中指定計時器IDlpTimerFunc參數不為NULL而指定為TimerProc函數的指針。這種方法使用TimerProc函數(名字可自定)處理WM_TIMER消息

             

            VOID CALLBACK TimerProc ( HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
            {
             //處理WM_TIMER訊息
            }

               TimerProc的參數hwnd是在調用SetTimer時指定的窗口句柄。Windows只把WM_TIMER消息送給TimerProc,因此消息參數總是等于WM_TIMER。iTimerID值是計時器ID,dwTimer值是與從GetTickCount函數的返回值相容的值。這是自Windows啟動后所經過的毫秒數。 使用這種方法時,相關函數調用的形式為:

             

            SetTimer(hWnd,ID_TIMER,1000,TimerProc) ;
            KillTimer(hWnd,ID_TIMER) ;

              方法三:調用SetTimer時不指定窗口句柄(為NULL)iTimerID參數自然被忽略lpTimerFunc不為NULL而指定為TimerProc的指針。正如上面SetTimer的討論中所說的,此時SetTimer的返回值正是新建立的計時器的ID,需將這個ID保存以供KillTimer銷毀計時器時所用。當然,KillTimer的hWnd參數也置為NULL。這種方法同樣用TimerProc處理WM_TIMER消息

             

            UINT_PTR iTimerID ;
            iTimerID = SetTimer(NULL,0,1000,TimerProc) ;
            KillTimer(NULL,iTimerID) ;

              使用這種方法的好處是不必自己指定計時器ID,這樣就不必擔心用錯ID。

             

            使用多個計時器

              使用多個計時器只要在建立計時器時指定不同的ID。比如用上面所述方法一時的情況:

             

            #define TIMER_SEC 1
            #define TIMER_MIN 2

            然后使用兩個SetTimer來設定兩個計時器:
            SetTimer (hwnd, TIMER_SEC, 1000, NULL) ;
            SetTimer (hwnd, TIMER_MIN, 60000, NULL) ;

            WM_TIMER的處理如下所示:
            case WM_TIMER:
             switch (wParam)
             {
              case TIMER_SEC:
               //每秒一次的處理
               break ;
              case TIMER_MIN:
               //每分鐘一次的處理
               break ;
             }
             return 0 ;

             

             

            改變計時器的時間間隔

              如果想將一個已經存在的計時器設定為不同的時間間隔,可以簡單地用不同的時間值再次調用SetTimer。

             

            計時器精確嗎?

              計時器并不精確。有兩個原因:

              原因一:Windows計時器是硬件和ROM BIOS架構下之計時器一種相對簡單的擴充。回到Windows以前的MS-DOS程序寫作環境下,應用程式能夠通過攔截者稱為timer tick的BIOS中斷來實現時鐘或計時器。一些為MS-DOS編寫的程序自己攔截這個硬件中斷以實現時鐘和計時器。這些中斷每54.915毫秒產生一次,或者大約每秒18.2次。這是原始的IBM PC的微處理器頻率值4.772720 MHz被218所除而得出的結果。在Windows 98中,計時器與其下的PC計時器一樣具有55毫秒的解析度。在Microsoft Windows NT中,計時器的解析度為10毫秒。Windows應用程式不能以高于這些解析度的頻率(在Windows 98下,每秒18.2次,在Windows NT下,每秒大約100次)接收WM_TIMER消息。在SetTimer中指定的時間間隔總是截尾后tick數的整數倍。例如,1000毫秒的間隔除以54.925毫秒,得到18.207個tick,截尾后是18個tick,它實際上是989毫秒。對每個小于55毫秒的間隔,每個tick都會產生一個WM_TIMER消息。
              可見,計時器并不能嚴格按照指定的時間間隔發送WM_TIMER消息,它總要相差那么幾毫秒。

              即使忽略這幾個毫秒的差別,計時器仍然不精確。請看原因二:
              WM_TIMER消息放在正常的消息隊列之中,和其他消息排列在一起,因此,如果在SetTimer中指定間隔為1000毫秒,那么不能保證程序每1000毫秒或者989毫秒就會收到一個WM_TIMER消息。如果其他程序的執行事件超過一秒,在此期間內,您的程式將收不到任何WM_TIMER訊息。事實上, Windows對WM_TIMER消息的處理非常類似于對WM_PAINT消息的處理,這兩個消息都是低優先級的,程序只有在消息隊列中沒有其他消息時才接收它們。
              WM_TIMER還在另一方面和WM_PAINT相似:Windows不能持續向消息隊列中放入多個WM_TIMER訊息,而是將多余的WM_TIMER消息組合成一個消息。因此,應用程序不會一次收到多個這樣的消息,盡管可能在短時間內得到兩個WM_TIMER消息。應用程序不能確定這種處理方式所導致的WM_TIMER消息「遺漏」的數目。
              可見,WM_TIMER消息并不能及時被應用程序所處理,WM_TIMER在消息隊列中的延誤可能就不能用毫秒來計算了。

              由以上兩點,你不能通過在處理WM_TIMER時一秒一秒計數的方法來計時。如果要實現一個時鐘程序,可以使用系統的時間函數如GetLocalTime ,而在時鐘程序中,計時器的作用是定時調用GetLocalTime獲得新的時間并刷新時鐘畫面,當然這個刷新的間隔要等于或小于1秒。

            本文轉自:http://www.shnenglu.com/ivenher/articles/19969.html

            posted @ 2012-09-10 17:16 王海光 閱讀(599) | 評論 (0)編輯 收藏
            Wget.exe:http://gnuwin32.sourceforge.net/packages/wget.htm
            curl.exe:    http://curl.haxx.se/download.html

            wget.exe curl.exe下載命令
            curl.exe檢測下載文件是否正確-f,wget.exe生成下載文檔來檢測

            Download  wget http://127.0.0.1/update_ex.txt -O d:\2.txt -o c:\\DownLoad.txt
            Download  curl http://127.0.0.1/update_ex.txt -o d:\2.txt -f
            posted @ 2012-09-05 16:23 王海光 閱讀(584) | 評論 (0)編輯 收藏

            一、顯示對話框

            1.顯示模式對話框:

            CDialogDemo dlg;
            dlg.DoModal();

            2.顯示非模式對話框:

            CDialogDemo *dlg=new CDialogDemo(this);
            dlg->Create(IDD_GENERAL_CONTROL);
            dlg->ShowWindow(SW_SHOW);


            二、關閉對話框

            1.CDialog::OnOK();   //確定按鈕按下         CDialog::OnCancel(); //取消按鈕被按下

            2.CDialog::DestoryWindow();  

            3.CDialog::EndDialog(0);  

            注:CDialog::CloseWindow();     僅僅是最小化對話框
            PostMessage(WM_CLOSE)


            三、在模態對話框類中關閉自身對話框
            可以在模態對話框類中通過PostMessage(WM_CLOSE)來關閉自身對話框。關閉MessageBox對話框后模態對話框隨之關閉。

            相關代碼如下:

             1 BOOL CImportDataPromptDialog::OnInitDialog()
             2 {
             3     CDialog::OnInitDialog();
             4 
             5     // TODO:  Add extra initialization here
             6     HANDLE hThread = StartImportDataThread();
             7     if (!hThread)
             8     {
             9         LOG("啟動導入數據線程失敗")
            10     }
            11 
            12     return TRUE;  // return TRUE unless you set the focus to a control
            13     // EXCEPTION: OCX Property Pages should return FALSE
            14 }
            15 
            16 DWORD WINAPI CImportDataPromptDialog::ImportDataThread(LPVOID Param)
            17 {
            18     CImportDataPromptDialog* importDlg = (CImportDataPromptDialog*)Param;
            19 
            20     if (CImportLog::ExtractionXMLData(importDlg->m_sXmlFilePath, importDlg->m_sDBPath))
            21     {
            22         importDlg->MessageBox("導入數據成功","平臺", MB_ICONINFORMATION);
            23         importDlg->PostMessage(WM_CLOSE);
            24     }
            25     else
            26     {
            27         importDlg->MessageBox("導入數據失敗","平臺", MB_ICONEXCLAMATION);
            28         importDlg->PostMessage(WM_CLOSE);
            29     }
            30     
            31     return 0;
            32 }
            33 
            34 HANDLE CImportDataPromptDialog::StartImportDataThread()
            35 {
            36     LOG("啟動導入數據線程");
            37     CWinThread* hThread = AfxBeginThread((AFX_THREADPROC)CImportDataPromptDialog::ImportDataThread,(LPVOID)this);
            38 
            39     return (hThread->m_hThread);
            40 }


            相關函數詳解:

            CloseWindow 
            函數功能:該函數最小化指定的窗口,但并不銷毀該窗口。
              函數原型:BOOL CloseWindow(HWND hWnd);
              參數:
              hWnd:將要最小化的窗口的句柄。
              返回值:如果函數成功,返回值為非零;如果函數失敗,返回值為零。若想獲得更多錯誤信息,請調用GetLastError函數。
              備注:窗口尺寸被最小化成一個圖標,并移動到屏幕的圖標區域。系統顯示窗口的圖標而不顯示窗口,并在圖標下顯示窗口標題。應用程序必須使用DestroyWindow函數銷毀窗口。

            DestroyWindow  
            函數功能:銷毀指定的窗口。這個函數通過發送WM_DESTROY 消息和 WM_NCDESTROY 消息使窗口無效并移除其鍵盤焦點。這個函數還銷毀窗口的菜單,清空線程的消息隊列,銷毀與窗口過程相關的定時器,解除窗口對剪貼板的擁有權,打斷剪貼板器的查看鏈。
              函數原型:BOOL DestroyWindow( HWND hWnd // handle to window to destroy);
              hWnd :將被銷毀的窗口的句柄。
              返回值:如果函數成功,返回值為非零:如果函數失敗,返回值為零。若想獲得更多錯誤信息,請調用GetLastError函數。
              備注:一個線程不能使用本函數銷毀別的線程創建的窗口。如果這個窗口是一個不具有WS_EX_NOPARENTNOTIFY 樣式的子窗口,則銷毀窗口時將發WM_PARENTNOTIFY 消息給其父窗口。
              Windows CE: 本函數將不發送 WM_NCDESTROY 消息.

            EndDialog  
            函數功能:該函數清除一個模態對話框,并使系統中止對對話框的任何處理。
              函數原型:BOOL EndDialog(HWND hDlg,int nResult);
              參數:
              hDlg:表示要被清除的對話框窗口。
              NResult:指定從創建對話框函數返回到應用程序的值。
              返回值:如果函數調用成功,則返回值為非零值;如果函數調用失敗則返回值為零。若想獲得錯誤信息請調用GetLastError函數。
              備注:由DialogBox,DialogBoxParam、DialogBoxlndirect和DialogBoxlndirectParam函數創建的對話框一定要用EndDialog函數來清除。應用程序從對話框應用程序內部調用EndDialog函數,該函數不能為其他目的而供使用。對話框應用程序可以在任何時間調用EndDialog函數;甚至在WM_INITDIALOG消息處理過程中。如果應用程序在WM_INTDIALOG消息處理過程中調用該函數,則對話框在顯示和輸入焦點被設置之前對話框被清除。EndDialog函數并不立即清除對話框。而是設置一個標志,并且允許對話框應用程序把控制權返回系統。系統在試圖從應用程序隊列檢索下一個消息之前檢測標志。如果已經設置了標志則系統中止消息循環,清除對話框,且用nResUlt中的值作為從創建對話框的函數中返回的值。


            本文相關鏈接:http://blog.csdn.net/bbrsher/article/details/6088108

            posted @ 2012-09-05 14:44 王海光 閱讀(9813) | 評論 (0)編輯 收藏

            小結:

            WM_CREATE是所有窗口都能響應的消息,表明本窗口已經創建完畢.可以安全的使用這個窗口了,例如在它上面畫控件等等.這個狀態肯定是在調用ShowWindows()顯示窗口之前.

            WM_WM_INITDIALOG是對話框才能收到的消息,表明對話框及其所有子控件都創建完畢了,這個狀態肯定是調用顯示對話框的函數之前.所以可以在WM_WM_INITDIALOG對控件進行一些修改等.

            -------

            不要被MFC干擾了,MFC封裝了太多的東西,心里想著API的執行順序就行了。
            所有窗口都是在注冊窗口類之后調用CreateWindowEx來創建的,創建成功之后(HWND有效但CreateWindowEx尚未返回)系統自動發送WM_CREATE消息,所以你的OnCreate將被執行,在這里窗口已經創建成功了,你可以安全地創建各種子窗口。

            -------

            -------

            http://www.shnenglu.com/pwqonline/archive/2008/12/04/67806.html

            WM_CREATE消息響應函數和WM_INITDIALOG消息響應函數之區別

                      在響應WM_CREATE消息響應函數的時候,對話框及子控件還未創建完成,亦是說只是通知系統說要開始創建窗口啦,這個消息響應完之后,對話框和子控件才開始創建。因此在此消息響應函數中無法對控件進行修改和初始化。

                      而WM_INITDIALOG消息響應函數是在程序運行時,當其對話框和子控件全部創建完畢,將要顯示內容的時候發送的消息。因此可以在WM_INITDIALOG消息響應函數中添加對編輯框控件的初始化和修改。


            -------

            WM_CREATE消息用來產生子窗口控件,WM_CREATE是誰發出的,什么意思??

            當然是windows操作系統發出,所有消息都是由操作系統發出給程序的,分成進隊消息,和不進隊
            消息,wm_create不僅僅指子窗口產生,所有窗口在操作系統內部產生時,windows都會發出這個消息

             

            --------

             

            應用程序中處理消息的順序(轉)

            MFC應用程序中處理消息的順序

            1.AfxWndProc()      該函數負責接收消息,找到消息所屬的CWnd對象,然后調用AfxCallWndProc

            2.AfxCallWndProc() 該函數負責保存消息(保存的內容主要是消息標識符和消息參數)供應用程序以后使用,
                                然后調用WindowProc()函數

            3.WindowProc()      該函數負責發送消息到OnWndMsg()函數,如果未被處理,則調用DefWindowProc()函數

            4.OnWndMsg()        該函數的功能首先按字節對消息進行排序,對于WM_COMMAND消息,調用OnCommand()消息
                                響應函數,對于WM_NOTIFY消息
                                調用OnNotify()消息響應函數。任何被遺漏的消息將是一個窗口消息。OnWndMsg()函數搜
                                索類的消息映像,以找到一個
                                能處理任何窗口消息的處理函數。如果OnWndMsg()函數不能找到這樣的處理函數的話,則
                                把消息返回到WindowProc()函數,由它將消息發送給DefWindowProc()函數

            5.OnCommand()       該函數查看這是不是一個控件通知(lParam參數不為NULL,如果lParam參數為空的話,說明
                                該消息不是控件通知),如果它是,OnCommand()函數會試圖將消息映射到制造通知的控件;
                                如果他不是一個控件通知(或者如果控件拒絕映射的消息)OnCommand()就會調用OnCmdMsg()函數

            6.OnCmdMsg()        根據接收消息的類,OnCmdMsg()函數將在一個稱為命令傳遞(Command Routing)的過程中潛在的
                                傳遞命令消息和控件通知。
                                例如:如果擁有該窗口的類是一個框架類,則命令和通知消息也被傳遞到視圖和文檔類,并為該
                                類尋找一個消息處理函數

             

            MFC應用程序創建窗口的過程

            1.PreCreateWindow()   該函數是一個重載函數,在窗口被創建前,可以在該重載函數中改變創建參數
                                  (可以設置窗口風格等等)

            2.PreSubclassWindow() 這也是一個重載函數,允許首先子分類一個窗口

            3.OnGetMinMaxInfo()   該函數為消息響應函數,響應的是WM_GETMINMAXINFO消息,允許設置窗口的最大或者
                                  最小尺寸

            4.OnNcCreate()        該函數也是一個消息響應函數,響應WM_NCCREATE消息,發送消息以告訴窗口的客戶區
                                  即將被創建

            5.OnNcCalcSize()      該函數也是消息響應函數,響應WM_NCCALCSIZE消息,作用是允許改變窗口客戶區大小

            6.OnCreate()          該函數也是一個消息響應函數,響應WM_CREATE消息,發送消息告訴一個窗口已經被創建

            7.OnSize()            該函數也是一個消息響應函數,響應WM_SIZE消息,發送該消息以告訴該窗口大小已經
                                  發生變化

            8.OnMove()            消息響應函數,響應WM_MOVE消息,發送此消息說明窗口在移動

            9.OnChildNotify()     該函數為重載函數,作為部分消息映射被調用,告訴父窗口即將被告知一個窗口剛剛被
                                  創建

             

            MFC應用程序關閉窗口的順序(非模態窗口)

            1.OnClose()       消息響應函數,響應窗口的WM_CLOSE消息,當關閉按鈕被單擊的時候發送此消息

            2.OnDestroy()     消息響應函數,響應窗口的WM_DESTROY消息,當一個窗口將被銷毀時,發送此消息

            3.OnNcDestroy()   消息響應函數,響應窗口的WM_NCDESTROY消息,當一個窗口被銷毀后發送此消息

            4.PostNcDestroy() 重載函數,作為處理OnNcDestroy()函數的最后動作,被CWnd調用

             


            MFC應用程序中打開模式對話框的函數調用順序

            1.DoModal()             重載函數,重載DoModal()成員函數

            2.PreSubclassWindow()   重載函數,允許首先子分類一個窗口

            3.OnCreate()            消息響應函數,響應WM_CREATE消息,發送此消息以告訴一個窗口已經被創建

            4.OnSize()              消息響應函數,響應WM_SIZE消息,發送此消息以告訴窗口大小發生變化

            5.OnMove()              消息響應函數,響應WM_MOVE消息,發送此消息,以告訴窗口正在移動

            6.OnSetFont()           消息響應函數,響應WM_SETFONT消息,發送此消息,以允許改變對話框中控件的字體

            7.OnInitDialog()        消息響應函數,響應WM_INITDIALOG消息,發送此消息以允許初始化對話框中的控件,
                                    或者是創建新控件

            8.OnShowWindow()        消息響應函數,響應WM_SHOWWINDOW消息,該函數被ShowWindow()函數調用

            9.OnCtlColor()          消息響應函數,響應WM_CTLCOLOR消息,被父窗口發送已改變對話框或對話框上面控件
                                    的顏色

            10. OnChildNotify()     重載函數,作為WM_CTLCOLOR消息的結果發送

             

            MFC應用程序中關閉模式對話框的順序

            1.OnClose()        消息響應函數,響應WM_CLOSE消息,當"關閉"按鈕被單擊的時候,該函數被調用

            2.OnKillFocus()    消息響應函數,響應WM_KILLFOCUS消息,當一個窗口即將失去鍵盤輸入焦點以前被發送

            3.OnDestroy()      消息響應函數,響應WM_DESTROY消息,當一個窗口即將被銷毀時,被發送

            4.OnNcDestroy()    消息響應函數,響應WM_NCDESTROY消息,當一個窗口被銷毀以后被發送

            5.PostNcDestroy() 重載函數,作為處理OnNcDestroy()函數的最后動作被CWnd調用

             


            打開無模式對話框的順序

            1.PreSubclassWindow()    重載函數,允許用戶首先子分類一個窗口

            2.OnCreate()             消息響應函數,響應WM_CREATE消息,發送此消息以告訴一個窗口已經被創建

            3.OnSize()               消息響應函數,響應WM_SIZE消息,發送此消息以告訴窗口大小發生變化

            4.OnMove()               消息響應函數,響應WM_MOVE消息,發送此消息以告訴窗口正在移動

            5.OnSetFont()            消息響應函數,響應WM_SETFONT消息,發送此消息以允許改變對話框中控件的字體


            以上這些的執行都是按給定的順序執行!

            只有清楚的了解應用程序的執行順序,才能在編寫代碼的時候知道,在什么時候應該執行什么,以及在什么地方該處理什么!
            這只是本人總結的一點小小的經驗,希望能對MFC的初學者有所幫助!


            本文轉自:http://blog.csdn.net/srxumin/article/details/6059789
            posted @ 2012-09-05 14:31 王海光 閱讀(4538) | 評論 (0)編輯 收藏

                  VC中我們經常使用到快捷鍵,這里快捷鍵有多種,包括menu,button。另外還區分local的和global的, 其中local的職能在當前程序有焦點(被激活)時有效,而global的,則無論什么時候都有效,測試local的要優先于global的,就是如果當前激活窗口的快捷鍵與未激活窗口的快捷鍵重疊,當前激活窗口優先響應。

                  這里將快捷鍵分為menu和button兩種。

            menu添加local快捷鍵又分為兩種, 一種是直接與菜單項關聯的加速鍵,另一種就是自定義的加速鍵.

             
            第一種: 首先在資源文件Accelerator中添加快捷鍵資源 ID選擇你要關聯菜單項的名稱 然后再設置你的快捷鍵.什么?下一步?在.h文件中加入一個    HACCEL   hAccel;變量 然后在OnInitDialog或初始化中加入hAccel=::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MENU_MAIN));  后面的參數改成加速鍵的資源文件名.

            最后在PreTranslateMessage(MSG* pMsg) 中加入:
                if(::TranslateAccelerator(GetSafeHwnd(),hAccel,pMsg))   
                    return   true;


            這樣 以后只要在Accelerator資源文件中添加快捷鍵就可以了 
            注意: 添加快捷鍵的名字一定要與菜單名稱一樣 這樣才能響應.現在只需要在此菜單項中加入OnCommand消息的處理就可以了.


            第二種: 還是在資源文件Accelerator中添加快捷鍵資源 ID自己定義一個.然后再設置你的快捷鍵.下一步...就是在.h文件中定義一個快捷鍵對象
            HACCEL m_hAccel;

            然后在.cpp文件中初始
             m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_ACCELERATOR1));
            IDR_ACCELERATOR1為你的加速資源名稱.注意不是剛剛定義的加速鍵ID.

            再添加PreTranslateMessage消息處理 在里面加入以下代碼:
             //保存快捷鍵被啟用
             if(m_hAccel   !=   NULL)   
             {   
              if (TranslateAccelerator(m_hWnd, m_hAccel, pMsg))   
               return   TRUE;    
             }  

            再添加OnCommand消息處理 加入以下代碼:

            //響應加速鍵
              switch(LOWORD(wParam))   
              {   
              case  SHOW_DIAL0G:   //加速鍵ID   
            //...添加處理語句
              break;   
              case   SHOW_DIALOG_02:   //加速鍵ID   
            //...添加處理語句
              break;   
              }  


            menu添加global快捷鍵
            以對話框程序為例:

            在OnInitDialog中添加注冊熱鍵的代碼: 
            RegisterHotKey(GetSafeHwnd(),1001,NULL,VK_F2);//F2鍵 
            RegisterHotKey(GetSafeHwnd(),1002,MOD_ALT,'1');//Alt+1鍵 
            在 
            BEGIN_MESSAGE_MAP(CXXXDlg, CDialog) 
            ... 
            END_MESSAGE_MAP() 
            中添加WM_HOTKEY的消息映射: 
            ON_MESSAGE(WM_HOTKEY,&CXXXDlg::OnHotKey)//快捷鍵消息映射手動加入 
            在頭文件中添加OnHotKey的聲明: 
            protected: 
            afx_msg LRESULT OnHotKey(WPARAM wParam,LPARAM lParam);//手動加入.


            CPP中OnHotKey的實現代碼:

            //相應快捷鍵的消息映射 
            LRESULT CXXXDlg::OnHotKey(WPARAM wParam,LPARAM lParam) 

                if(wParam ==1001) 
                {  
                    MessageBox("熱鍵F2已經按下!"); 
                    //這里可以加上你按鈕要執行的操作,或者直接調用按鈕映射的消息函數 
                } 
                else if (wParam==1002) 
                { 
                    MessageBox("熱鍵ALT+1已經按下!"); 
                } 
                return 0; 

            關閉對話框時使用 
            UnregisterHotKey(GetSafeHwnd(),1001);//注銷F2鍵 
            UnregisterHotKey(GetSafeHwnd(),1002);//注銷Alt+1鍵 
            注銷熱鍵.

            button添加locak快捷鍵可以直接在button的caption中用 &+'X' 即可,則按下 Alt + 'x' 即按下此按鈕,起到快捷鍵的作用

            另外還可以學習menu添加local快捷鍵的第二種方式,在PreTranslateMessage中添加處理函數。

            button添加global快捷鍵同menu添加global快捷鍵。


            加載資源(MFC的Dialog   Based中): 
            HACCEL   hAcc   =   LoadAccelerators   (m_hInstance,   MAKEINTRESOURCE(IDR_ACCELERATOR1)); 
            需要在 
            PreTranslateMessage中一行 
            if   (TranslateAccelerator(GetSafeHwnd(),   m_hAcc,   pMsg))return   TRUE;
            LoadAccelerators的結果最好保存在一個成員變量中。

            本文轉自:http://blog.163.com/lvlijuan001@126/blog/static/77997198201110147301101/
            posted @ 2012-09-05 13:58 王海光 閱讀(1513) | 評論 (0)編輯 收藏
                 摘要: PreTranslateMessage作用和使用方法          PreTranslateMessage是消息在送給TranslateMessage函數之前被調用的,絕大多數本窗口的消息都要通過這里,比較常用,當需要在MFC之前處理某些消息時,常常要在這里添加代碼.    &n...  閱讀全文
            posted @ 2012-09-05 12:48 王海光 閱讀(1738) | 評論 (0)編輯 收藏

            在Windows平臺做開發肯定會接觸到UI程序的編寫,以MFC的UI開發為例,可以開發單文檔,多文檔,對話框等形式的應用。寫一個UI程序容易,寫好卻不是一件簡單的事情。在整個代碼結構的清晰性與可維護性方面需要多加注意。寫好UI程序需求注意以下幾點:

             

            1、圍繞數據編程與不是圍繞UI編程

             

            當我們拿到需求最先接觸到的就是UI的設計,也許是美工畫的,也許是設計草圖。工程師在具體設計的時候容易受UI的影響,或者干脆從UI開始編程。

             

            這是一個錯誤的編程習慣,無論UI如何展現與交互,最終都應該圍繞數據編程。拿到需求后,應該先思考和推敲數據的設計與流轉,UI不過就是數據的一種展現形式而已。

             

            2、做好UI與邏輯的解耦

             

            UI的編程會涉及到許多控件的操作,消息的處理,不知不覺,一個UI類的代碼會越寫越大,以至于一段時間以后,瀏覽和梳理都會變得不太方便。

             

            在UI類里,除了與UI本身的操作有關的代碼以外,任何邏輯代碼都應該與此解耦,并根據具體情況進行封裝調用。如果一個控件關聯了太多數據操作,應該把這些操作封裝到控件的繼承類中,把一類代碼進行集中管理和維護。

             

            上述問題,在程序寫作的初期還不太明顯,隨著代碼逐漸膨脹,會越會越讓人難以忍受。

             

            3、數據單向依賴,單向更新

             

            UI圍繞的數據進行展現與更新,在這個過程中,所以對數據的操作應該進行封裝,而不是散落在UI程序在各個角落,數據的更新、獲取和UI傳遞消息時,應該單向操作,如果出現循環處理的情況,在以后維護調試的BUG的過程中會變得比較困難,導致維護效率下降。

             

            本文來自CSDN博客,轉載請標明出處:http://www.shnenglu.com/humanchao

            posted @ 2012-09-05 10:45 王海光 閱讀(521) | 評論 (0)編輯 收藏

            獲取驅動相關文件列表可用DRIVER_INFO_3,GetPrinterDriver

            MSDN中解釋:

            DRIVER_INFO_3

            The DRIVER_INFO_3 structure contains printer driver information.

            typedef struct _DRIVER_INFO_3 { 
              DWORD  cVersion; 
              LPTSTR pName; 
              LPTSTR pEnvironment; 
              LPTSTR pDriverPath; 
              LPTSTR pDataFile; 
              LPTSTR pConfigFile; 
              LPTSTR pHelpFile; 
              LPTSTR pDependentFiles; 
              LPTSTR pMonitorName; 
              LPTSTR pDefaultDataType; 
            } DRIVER_INFO_3, *PDRIVER_INFO_3; 

            Members

            cVersion
            Specifies the operating system version for which the driver was written. It can be one of the following.
            Value Meaning
            0 Driver for Windows 95/98/Me.
            2 Driver for Windows NT 4.0.
            3 Driver for Windows 2000/XP.

            pName
            Pointer to a null-terminated string that specifies the name of the driver (for example, "QMS 810").
            pEnvironment
            Pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows NT x86, Windows IA64, Windows x64, Windows NT R4000, Windows NT Alpha_AXP, Windows 4.0, or Windows NT PowerPC).
            Note Windows IA64 is available in Windows XP, Windows XP 64-Bit Edition, Windows Server 2003, and later versions. Windows x64 is available in Windows XP Service Pack 2 (SP2), Windows XP Professional x64 Edition, Windows Server 2003 Service Pack 1 (SP1), and later versions.
            pDriverPath
            Pointer to a null-terminated string that specifies a file name or full path and file name for the file that contains the device driver (for example, "C:\DRIVERS\Pscript.dll").
            pDataFile
            Pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains driver data (for example, "C:\DRIVERS\Qms810.ppd").
            pConfigFile
            Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's configuration dynamic-link library (for example, "C:\DRIVERS\Pscrptui.dll").
            pHelpFile
            Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's help file.
            pDependentFiles
            Pointer to a null-terminated string that specifies the files the driver is dependent on. Each file name in the string is also terminated with a null (for example, "Pscript.dll\0Qms810.PPD\0Pscrptui.dll\0Pspcriptui.hlp\0Pstest.txt\0\0").
            pMonitorName
            Pointer to a null-terminated string that specifies a language monitor (for example, "PJL monitor"). This member can be NULL and should be specified only for printers capable of bidirectional communication.
            pDefaultDataType
            Pointer to a null-terminated string that specifies the default data type of the print job (for example, "EMF").

            Requirements

              Windows NT/2000/XP/Vista: Included in Windows NT 4.0 and later.
              Windows 95/98/Me: Included in Windows 95 and later.
              Header: Declared in Winspool.h; include Windows.h.
              Unicode: Declared as Unicode and ANSI structures.

            GetPrinterDriver

            The GetPrinterDriver function retrieves driver data for the specified printer. If the driver is not installed on the local computer, GetPrinterDriver installs it.

            BOOL GetPrinterDriver(
              HANDLE hPrinter,     // printer object
              LPTSTR pEnvironment, // environment name
              DWORD Level,         // information level
              LPBYTE pDriverInfo,  // driver data buffer
              DWORD cbBuf,         // size of buffer
              LPDWORD pcbNeeded    // bytes received or required
            );

            Parameters

            hPrinter
            [in] Handle to the printer for which the driver data should be retrieved. Use the OpenPrinter or AddPrinter function to retrieve a printer handle.
            pEnvironment
            [in] Pointer to a null-terminated string that specifies the environment (for example, Windows NT x86, Windows IA64, Windows x64, Windows NT R4000, Windows NT Alpha_AXP, Windows 4.0, or Windows NT PowerPC). If this parameter is NULL, the current environment of the calling application and client machine (not of the destination application and print server) is used.
            Note Windows IA64 is available in Windows XP, Windows XP 64-Bit Edition, Windows Server 2003, and later versions. Windows x64 is available in Windows XP Service Pack 2 (SP2), Windows XP Professional x64 Edition, Windows Server 2003 Service Pack 1 (SP1), and later versions.
            Level
            [in] Specifies the printer driver structure returned in the pDriverInfo buffer. This parameter can be one of the following values.
            Level Structure
            1 DRIVER_INFO_1
            2 DRIVER_INFO_2
            3 Windows 95/98/Me, Windows NT4.0 and later: DRIVER_INFO_3
            4 Windows 2000/XP: DRIVER_INFO_4
            5 Windows 2000/XP: DRIVER_INFO_5
            6 Windows Me, Windows 2000/XP: DRIVER_INFO_6

            pDriverInfo
            [out] Pointer to a buffer that receives a structure containing information about the driver, as specified by Level. The buffer must be large enough to store the strings pointed to by the structure members.

            To determine the required buffer size, call GetPrinterDriver with cbBuf set to zero. GetPrinterDriver fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and the pcbNeeded parameter returns the size, in bytes, of the buffer required to hold the array of structures and their data.

            cbBuf
            [in] Specifies the size, in bytes, of the array at which pDriverInfo points.
            pcbNeeded
            [out] Pointer to a value that receives the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

            Return Values

            If the function succeeds, the return value is a nonzero value.

            If the function fails, the return value is zero. To get extended error information, call GetLastError.

            Windows 95/98/Me: For a non-existent driver, the function returns ERROR_INVALID_NAMES.

            Windows NT/2000/XP: For a non-existent driver, the function returns ERROR_UNKNOWN_PRINTER_DRIVER.

            Remarks

            The DRIVER_INFO_2, DRIVER_INFO_3, DRIVER_INFO_4, DRIVER_INFO_5, and DRIVER_INFO_6 structures contain the file name or the full path and file name of the printer driver in the pDriverPath member. An application can use the path and file name to load a printer driver by calling the LoadLibrary function and supplying the path and file name as the single argument.

            Requirements

              Windows NT/2000/XP/Vista: Included in Windows NT 3.1 and later.
              Windows 95/98/Me: Included in Windows 95 and later.
              Header: Declared in Winspool.h; include Windows.h.
              Library: Use Winspool.lib.
              Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000/XP.


            相關代碼:

             1 BOOL CCommonFun::GetPrinterDriverInfo(HANDLE hPrinter, CStringArray &arsDriverFiles, CString &sDriverInstallPath)
             2 {
             3     DWORD dwNeed = 0;
             4     BOOL bOK = GetPrinterDriver(hPrinter, NULL, 3, NULL, NULL, &dwNeed);
             5     if (dwNeed > 0)
             6     {
             7         BYTE *pData = new BYTE[dwNeed];
             8 
             9         bOK = GetPrinterDriver(hPrinter, NULL, 3, pData, dwNeed, &dwNeed);
            10         if(bOK)
            11         {
            12             DRIVER_INFO_3 *pInfo3 = (DRIVER_INFO_3*)pData;
            13             sDriverInstallPath = GetFilePath(pInfo3->pDriverPath);
            14             if (sDriverInstallPath.IsEmpty())
            15             {
            16                 return FALSE;
            17             }
            18             //GetFileList
            19             arsDriverFiles.Add(GetFileFullName(pInfo3->pDriverPath));            
            20             arsDriverFiles.Add(GetFileFullName(pInfo3->pDataFile));        
            21             arsDriverFiles.Add(GetFileFullName(pInfo3->pConfigFile));
            22             arsDriverFiles.Add(GetFileFullName(pInfo3->pHelpFile));
            23 
            24             LPSTR __pdependentFiles = pInfo3->pDependentFiles;
            25             CString dependentFiles;
            26             //get dependent files
            27             if (__pdependentFiles)
            28             {
            29                 while (__pdependentFiles[0!= '\0')
            30                 {
            31                     dependentFiles = GetFileFullName(__pdependentFiles);
            32                     arsDriverFiles.Add(dependentFiles);
            33                     __pdependentFiles += (strlen(__pdependentFiles)+1);
            34                 }
            35             }
            36         }
            37         else
            38         {
            39             return FALSE;
            40         }
            41 
            42         delete []pData;
            43     }
            44     else
            45     {
            46         return FALSE;
            47     }
            48 
            49     return TRUE;
            50 }

             

            posted @ 2012-09-04 17:51 王海光 閱讀(607) | 評論 (0)編輯 收藏

            實例代碼:

             1 #define USER_NAME     ("姓名")
             2 #define USER_ROLE     ("學生/教師")
             3 #define USER_CLASS    ("班級")
             4 #define USER_ACCOUNT  ("用戶名")
             5 
             6     ListView_SetExtendedListViewStyle(m_nameList.GetSafeHwnd(), m_nameList.GetExStyle() | LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES);
             7     RECT rect;
             8     m_nameList.GetWindowRect(&rect);
             9     int avageWidth = (rect.right - rect.left)/COLUMN_COUNT;
            10 
            11     LPSTR columnName[] ={USER_NAME,USER_ROLE,USER_CLASS,USER_ACCOUNT};
            12 
            13     int   widths[]={avageWidth-10,avageWidth-20,avageWidth+10,avageWidth}; 
            14     LV_COLUMN   lvc; 
            15     lvc.mask=LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; 
            16     lvc.fmt=LVCFMT_LEFT; 
            17     for(int i=0;i <COLUMN_COUNT;i++)   
            18     {//insert a row 
            19         lvc.pszText=columnName[i]; 
            20         lvc.cx=widths[i]; 
            21         lvc.iSubItem=i; 
            22         m_nameList.InsertColumn(i,&lvc); 
            23     }

             

            posted @ 2012-09-04 17:44 王海光 閱讀(784) | 評論 (0)編輯 收藏
            僅列出標題
            共27頁: First 14 15 16 17 18 19 20 21 22 Last 
            亚洲中文久久精品无码| 久久99热这里只有精品66| 国内精品免费久久影院| 久久国产AVJUST麻豆| 一本色综合网久久| 久久青草国产精品一区| 无码国内精品久久综合88| 国产精品天天影视久久综合网| 一级A毛片免费观看久久精品| 久久精品国产亚洲一区二区三区| 久久精品国产亚洲一区二区| 精品久久久久久久久中文字幕| 精品久久久久久久久久久久久久久| 国产欧美久久久精品影院| 国产精品一区二区久久国产| 99久久国产精品免费一区二区| 久久精品视频免费| 色偷偷久久一区二区三区| 国产亚洲精久久久久久无码77777| 国产精品天天影视久久综合网| 99久久综合国产精品免费| 色综合久久中文色婷婷| 亚洲国产精品高清久久久| 精品久久久久久久久午夜福利| 2021最新久久久视精品爱| 久久国产精品二国产精品| 久久精品国产精品国产精品污 | 国产亚洲色婷婷久久99精品| 久久精品无码av| 超级碰久久免费公开视频| 国内精品久久久久影院网站| 国产成人综合久久综合| 久久久久久午夜成人影院| 国产激情久久久久影院老熟女| 国产午夜精品久久久久免费视| 久久久久久久97| 国产一久久香蕉国产线看观看| 亚洲国产精品久久久天堂| 久久久久久亚洲Av无码精品专口 | 2021少妇久久久久久久久久| 热re99久久6国产精品免费|