现在的位置: 首页 > 综合 > 正文

windows程序设计 之 「HEAD」范例分析笔记

2013年11月04日 ⁄ 综合 ⁄ 共 7847字 ⁄ 字号 评论关闭

/*---------------------------------------------
   HEAD.C -- Displays beginning (head) of file
             (c) Charles Petzold, 1998
  ---------------------------------------------*/

 

#include <windows.h>

#define ID_LIST     1
#define ID_TEXT     2

#define MAXREAD     8192
#define DIRATTR     (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM | /
                                DDL_DIRECTORY | DDL_ARCHIVE  | DDL_DRIVES)
                    
                     //DT_WORDBREAK:断开字,当一行中的字符将会延伸到由lpRect指定的矩形的边框时,此行自动地在字之间断开。
                     //DT_EXPANDTABS:扩展制表符,每个制表符的缺省字符数是8
                     //DT_NOCLIP:无裁剪绘制
                     //DT_NOPREFIX:关闭前缀字符的处理.通常DrawText解释助记前缀字符,&为给其后的字符加下划线,

                     //解释&&为显示单个&。指定DT_NOPREFIX,这种处理被关闭。
#define DTFLAGS     (DT_WORDBREAK | DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX)

 

LRESULT CALLBACK WndProc  (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ListProc (HWND, UINT, WPARAM, LPARAM) ;

 

WNDPROC OldList ;

 

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("head") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
    
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
    
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }

 

     //WS_CLIPCHILDREN:当在父窗口内绘图时,排除子窗口区域。在创建父窗口时使用这个风格
     hwnd = CreateWindow (szAppName, TEXT ("head"),
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
    
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
    
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

 

 

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static BOOL       bValidFile ;
     static BYTE        buffer[MAXREAD] ;
     static HWND     hwndList, hwndText ;
     static RECT       rect ;
     static TCHAR    szFile[MAX_PATH + 1] ;  //windows的MAX_PATH是260   盘符+:/+结尾的0+256=260
     HANDLE           hFile ;
     HDC                 hdc ;
     int                    i, cxChar, cyChar ;
     PAINTSTRUCT     ps ;
     TCHAR             szBuffer[MAX_PATH + 1] ;
    
     switch (message)
     {
     case WM_CREATE :
          cxChar = LOWORD (GetDialogBaseUnits ()) ;
          cyChar = HIWORD (GetDialogBaseUnits ()) ;
         
          rect.left = 20 * cxChar ;
          rect.top  =  3 * cyChar ; //计算得出用于显示文件具体信息的窗口区域
         
          hwndList = CreateWindow (TEXT ("listbox"), NULL,
                              WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD,
                              cxChar, cyChar * 3,
                              cxChar * 13 + GetSystemMetrics (SM_CXVSCROLL),
                              cyChar * 10,
                              hwnd, (HMENU) ID_LIST,
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;

          GetCurrentDirectory (MAX_PATH + 1, szBuffer) ;  //装载程序进程的当前目录到szBuffer
         
          hwndText = CreateWindow (TEXT ("static"), szBuffer,
                              WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,
                              cxChar, cyChar, cxChar * MAX_PATH, cyChar,
                              hwnd, (HMENU) ID_TEXT,
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;
                             
          //将句柄为hwndList的子窗口控件的窗口消息处理程序挂钩到ListProc函数
          OldList = (WNDPROC) SetWindowLong (hwndList, GWL_WNDPROC, (LPARAM) ListProc) ;


          //添加程序进程当前目录下的文件列表到清单方块控件中
          SendMessage (hwndList, LB_DIR, DIRATTR, (LPARAM) TEXT ("*.*")) ;
          return 0 ;
         
     case WM_SIZE :
          //得到用于显示文件具体信息的窗口区域
          rect.right  = LOWORD (lParam) ;
          rect.bottom = HIWORD (lParam) ;
          return 0 ;
         
     case WM_SETFOCUS :
          //父窗口直接转移焦点到清单方块控件上
          SetFocus (hwndList) ;
          return 0 ;
         
     case WM_COMMAND :
          //如果在清单方块控件中执行双击
          if (LOWORD (wParam) == ID_LIST && HIWORD (wParam) == LBN_DBLCLK
          {
                     //获得选中项目的索引
               if (LB_ERR == (i = SendMessage (hwndList, LB_GETCURSEL, 0, 0))) 
                    break ;
                   
               //保存双击的文件名称到szBuffer
               SendMessage (hwndList, LB_GETTEXT, i, (LPARAM) szBuffer) ;
              
                // INVALID_HANDLE_VALUE 表无效句柄值
                //CreateFile(指向文件名的指针,访问模式,共享模式,指向安全属性的指针,
                //           如何创建,文件属性,用于复制文件句柄);    执行成功返回文件句柄

               if (INVALID_HANDLE_VALUE != (hFile = CreateFile (szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL,
                                                                                                OPEN_EXISTING, 0, NULL)))

               {
                    CloseHandle (hFile) ; //关闭文件句柄
                    bValidFile = TRUE ;
                    lstrcpy (szFile, szBuffer) ; //复制文件名到szFile
                    GetCurrentDirectory (MAX_PATH + 1, szBuffer) ; //装载进程的当前目录到 szBuffer

 

                    //   ‘//’第一个/为转义字符 第2个才是显示的/
                    //该语句将一个 / 追加在szBuffer后面

                    if (szBuffer [lstrlen (szBuffer) - 1] != '//')
                         lstrcat (szBuffer, TEXT ("//")) ;
                        
                    //将选中的文件绝对路径输出到静态控件上
                    SetWindowText (hwndText, lstrcat (szBuffer, szFile)) ;
               }
               else
               {
                    bValidFile = FALSE ;
                    szBuffer [lstrlen (szBuffer) - 1] = '/0' ;

                         //如果设置该目录不工作,也许这是一个磁盘驱动器,所以试试。
                    if (!SetCurrentDirectory (szBuffer + 1)) //设置当前目录,返回值非零表示成功,零表示失败

                    {  

                         //如果失败,用szBuffer + 2来设置磁盘驱动器
                         szBuffer [3] = ':' ;
                         szBuffer [4] = '/0' ;
                         SetCurrentDirectory (szBuffer + 2) ; 
                    }

 

                    GetCurrentDirectory (MAX_PATH + 1, szBuffer) ;
                    SetWindowText (hwndText, szBuffer) ;
                    //LB_RESETCONTENT清除清单方块中的内容
                    SendMessage (hwndList, LB_RESETCONTENT, 0, 0) ;
                    //文件目录重新写入清单方块
                    SendMessage (hwndList, LB_DIR, DIRATTR,  (LPARAM) TEXT ("*.*")) ;
               }
               InvalidateRect (hwnd, NULL, TRUE) ;
          }
          return 0 ;
         
     case WM_PAINT :
          if (!bValidFile)
               break ;

          if (INVALID_HANDLE_VALUE == (hFile = CreateFile (szFile, GENERIC_READ,
                    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
          {
               bValidFile = FALSE ;
               break ;
          }
         
          //ReadFile(文件句柄,用于保存读入数据的缓冲区,要读入的字符数,指向实际读取字节数的指针,(没有异步操作)NULL);
          ReadFile (hFile, buffer, MAXREAD, (unsigned long*)&i, NULL) ;
          CloseHandle (hFile) ;

 

          // i 现在等于缓冲区的实际字节数.
          hdc = BeginPaint (hwnd, &ps) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT)) ;
          SetBkColor   (hdc, GetSysColor (COLOR_BTNFACE)) ;

 

          //用ASCII字符集显示读取到的数据信息
          DrawTextA (hdc, (const char*)buffer, i, &rect, DTFLAGS) ;
         
          EndPaint (hwnd, &ps) ;
          return 0 ;
         
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
    
LRESULT CALLBACK ListProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        //如果消息是按下回车键,便向父窗口发送清单方块双击的消息
     if (message == WM_KEYDOWN && wParam == VK_RETURN)
          SendMessage (GetParent (hwnd), WM_COMMAND,
         //MAKELONG是一个宏,将两个16位的数联合成一个无符号的32位数。第一个参数是低十六位。
                       MAKELONG (1, LBN_DBLCLK), (LPARAM) hwnd) ;
         
     return CallWindowProc (OldList, hwnd, message, wParam, lParam) ;
}

抱歉!评论已关闭.