windows 程序设计之「TESTMCI.C」范例分析笔记

/*----------------------------------------

   TESTMCI.C -- 交谈式输入MCI命令

                (c) Charles Petzold, 1998

  ----------------------------------------*/

 

#include <windows.h>

#include "resource.h"

 

#define ID_TIMER    1

 

BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM) ;

 

TCHAR szAppName [] = TEXT ("TestMci") ;

 

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow)

{

     if (-1 == DialogBox (hInstance, szAppName, NULL, DlgProc))

     {

          MessageBox (NULL, TEXT ("This program requires Windows NT!"),

                      szAppName, MB_ICONERROR) ;

     }

     return 0 ;

}

 

BOOL CALLBACK DlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

     static HWND hwndEdit ;

     int         iCharBeg, iCharEnd, iLineBeg, iLineEnd, iChar, iLine, iLength ;

     MCIERROR    error ;

     RECT        rect ;

     TCHAR       szCommand [1024], szReturn [1024],

                 szError [1024], szBuffer [32] ;

 

     switch (message)

     {

     case WM_INITDIALOG: // 对话框建立时

         // 获取对话框大小

          GetWindowRect (hwnd, &rect) ;

        // 该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z

          SetWindowPos (hwnd, NULL,

              // 获取屏幕宽度 - 窗口右边坐标 + 窗口左边坐标 = 减去程序窗口后屏幕所剩宽度 / 2

              // 该参数用于定位窗口水平位置(上面的算法使窗口水平居中)

               (GetSystemMetrics (SM_CXSCREEN) - rect.right + rect.left) / 2,

              // 使窗口垂直居中

               (GetSystemMetrics (SM_CYSCREEN) - rect.bottom + rect.top) / 2,

              // 0,0 这两个参数用于改变窗口大小

              // SWP_NOZORDER 维持当前Z(忽略参数二)

              // SWP_NOSIZE   维持当前尺寸(忽略之前两个参数)

               0, 0, SWP_NOZORDER | SWP_NOSIZE) ;

          // 索检对话框中的文字编辑控件的句柄

          hwndEdit = GetDlgItem (hwnd, IDC_MAIN_EDIT) ;

          // 使文字输入控件具有键盘焦点

          SetFocus (hwndEdit) ;

          // windows传回FALSE,这告诉系统不用设置焦点

          return FALSE ;

 

     case WM_COMMAND:

          switch (LOWORD (wParam))

          {

          case IDOK:

                    // Find the line numbers corresponding to the selection

              // 向文字编辑控件发送EM_GETSEL消息,获取当前选择的字符开始和结尾的偏移量

              // 如果没有选取任何字符,则缓冲区中记录的是当前插入符的位置

               SendMessage (hwndEdit, EM_GETSEL, (WPARAM) &iCharBeg,

                                                 (LPARAM) &iCharEnd) ;

               // EM_LINEFROMCHAR 消息获取文字编辑控件中 wParam 参数位置所在的行号,从零开始

               iLineBeg = SendMessage (hwndEdit, EM_LINEFROMCHAR, iCharBeg, 0) ;

               iLineEnd = SendMessage (hwndEdit, EM_LINEFROMCHAR, iCharEnd, 0) ;

 

               // 遍历选择的所有行

               for (iLine = iLineBeg ; iLine <= iLineEnd ; iLine++)

               {

                         // Get the line and terminate it; ignore if blank

 

                    * (WORD *) szCommand = sizeof (szCommand) / sizeof (TCHAR) ;

                    // EM_GETLINE 消息复制一行字符到指定的缓冲区中,返回复制的字符数

                    iLength = SendMessage (hwndEdit, EM_GETLINE, iLine,

                                                     (LPARAM) szCommand) ;

                    szCommand [iLength] = '/0' ;

                    // 如果该行为空,则立刻执行下一次循环迭代

                    if (iLength == 0)

                         continue ;

 

                   /* MCI发送命令

                      szCommand   指向以null结尾的命令字符串:"命令 设备[ 参数]"

                      szReturn    指向接收返回信息的缓冲区,为NULL时不返回信息

                      参数三      指出接收返回信息的缓冲区的大小

                      hwnd        在命令串中含notify时,它指定一个回调窗口的句柄 */

                    error = mciSendString (szCommand, szReturn,

                              sizeof (szReturn) / sizeof (TCHAR), hwnd) ;

 

                    // 将返回信息显示在IDC_RETURN_STRING控件中

                    SetDlgItemText (hwnd, IDC_RETURN_STRING, szReturn) ;

 

                   // 获取错误字符串字段(即使没有错误)

                    mciGetErrorString (error, szError,

                                       sizeof (szError) / sizeof (TCHAR)) ;

 

                    // 输出错误信息在IDC_ERROR_STRING控件中

                    SetDlgItemText (hwnd, IDC_ERROR_STRING, szError) ;

               }

                    // Send the caret to the end of the last selected line

               // 获取iLineEnd行号的第一个字符在编辑控件中以零开始的偏移量

               iChar  = SendMessage (hwndEdit, EM_LINEINDEX,  iLineEnd, 0) ;

               // EM_LINELENGTH 消息获取iCharEnd 字符所在行的字符长度

               iChar += SendMessage (hwndEdit, EM_LINELENGTH, iCharEnd, 0) ;

               // 由于最后两个参数一样,所以只是设置插入符的位置到用户选择的字符所在行的下一行

               SendMessage (hwndEdit, EM_SETSEL, iChar, iChar) ;

              

               // EM_REPLACESEL 消息替换当前选中的字符

               // FALSE 表示替换的字符不可撤销

               // 由于当前未选中字符,所以只是插入了一个换行符

               // /r 是回车,return   /n 是换行,newline (历史遗留问题)

               SendMessage (hwndEdit, EM_REPLACESEL, FALSE,

                                      (LPARAM) TEXT ("/r/n")) ;

               SetFocus (hwndEdit) ;

               return TRUE ;

 

          case IDCANCEL:

               EndDialog (hwnd, 0) ;

               return TRUE ;

 

          case IDC_MAIN_EDIT:

              // 无法分配足够的内存来满足特定的要求时

               if (HIWORD (wParam) == EN_ERRSPACE)

               {

                    MessageBox (hwnd, TEXT ("Error control out of space."),

                                szAppName, MB_OK | MB_ICONINFORMATION) ;

                    return TRUE ;

               }

               break ;

          }

          break ;

 

          // mciSendString函数传回控制权后,如果指定notify标记,则收到此消息

     case MM_MCINOTIFY:

         // 使IDC_NOTIFY_MESSAGE控件接受鼠标键盘输入

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_MESSAGE), TRUE) ;

 

          wsprintf (szBuffer, TEXT ("Device ID = %i"), lParam) ;

          SetDlgItemText (hwnd, IDC_NOTIFY_ID, szBuffer) ;

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_ID), TRUE) ;

 

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_SUCCESSFUL),

                              wParam & MCI_NOTIFY_SUCCESSFUL) ;

         

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_SUPERSEDED),

                              wParam & MCI_NOTIFY_SUPERSEDED) ;

 

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_ABORTED),

                              wParam & MCI_NOTIFY_ABORTED) ;

 

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_FAILURE),

                              wParam & MCI_NOTIFY_FAILURE) ;

 

          SetTimer (hwnd, ID_TIMER, 5000, NULL) ;

          return TRUE ;

 

     case WM_TIMER:

          KillTimer (hwnd, ID_TIMER) ;

 

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_MESSAGE), FALSE) ;

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_ID), FALSE) ;

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_SUCCESSFUL), FALSE) ;

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_SUPERSEDED), FALSE) ;

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_ABORTED), FALSE) ;

          EnableWindow (GetDlgItem (hwnd, IDC_NOTIFY_FAILURE), FALSE) ;

          return TRUE ;

 

     case WM_SYSCOMMAND:

          switch (LOWORD (wParam))

          {

          case SC_CLOSE:

               EndDialog (hwnd, 0) ;

               return TRUE ;

          }

          break ;

     }

     return FALSE ;

}

 

 

你可能感兴趣的:(windows,timer,String,null,callback,newline)