No MFC,Only API——選單的建立和使用 (轉)

gugu99發表於2008-05-02
No MFC,Only API——選單的建立和使用 (轉)[@more@] No MFC,Only ——選單的建立和使用::namespace prefix = o ns = "urn:schemas--com::office" />

在使用選單之前,值得一提的是,包含選單的視窗必須是POPUP-UP或OVERLAPPED風格,才可能擁有選單。

選單的建立有三種方法:1,在WINDOWCLASS中指定選單資源的識別符號;2,在CreateWindowEx引數中指定選單控制程式碼;3,先用LoadMenu函式載入選單資源,再用SetMenu函式把選單載入到應用的選單欄。

選單的操作包含:向已存在選單新增新的選單項,刪除選單中的某一項,使選單項呈現被選中狀態,使選單項無效,建立浮動式選單,向選單中新增,刪除選項等等。

定位選單項有兩種途徑:1,用選單項的唯一識別符號;2,用選單項的邏輯。

選單項的邏輯索引是這樣規定的,選單欄中的項從左到右的索引依次是0,1,2...,彈出選單中的項從上到下的索引依次是0,1,2...。

如果想獲得選單某一項的控制程式碼,因先獲得選單條的控制程式碼,在用該選單項的索引取得控制程式碼。例如:

hMenu=GetMenu(hWnd);   //hWnd是視窗控制程式碼

hPopupMenu=GetSubMenu(hMenu,0);  //0表示選單的第一個選項

 

範例1:演示選單的各種操作

 

// begin.cpp : Defines the entry point for the application.

//

#define _LEAN_AND_MEAN

#include "stdafx.h"

#include "re.h"

#define ID_NEWITEM 1013      //定義新選單項的識別符號

#define ID_NEWSYSITEM 60441    //定義新系統選單項識別符號

 

LRESULT CALLBACK MainProc(HWND,UINT,WPARAM,LPARAM);  //主視窗函式

BOOL WINAPI DoDispPopupMenu(HWND,int,int);    //建立彈出式選單

VOID WINAPI DoDispMessage(int);        //顯示相關資訊 

VOID WINAPI DoInsertMenuItem(void);      //向已有選單中插入新項

VOID WINAPI DoDeleteMenuItem(void);      //刪除選單中的選項

VOID WINAPI DoCheckMenuItem(void);      //設定選單項為選中標誌

VOID WINAPI DoCheckRadio(void);        //設定選單項為單選標誌

VOID WINAPI DoInsertSysMenu(void);      //向系統選單中插入新項

 

char szAppName[]="Begin";

HINSTANCE hIns;

HWND hMainWnd;

BOOL isInsert;    //插入選單標誌

BOOL isCheck;      //選中標誌

int  idRadio=2;    //單選標誌

 

int APIENTRY WinMain(HINSTANCE hInstance,

  HINSTANCE hPrevInstance,

  LPSTR  lpCmdLine,

   int  nCmdShow)

{

  MSG msg;

  HWND hWnd;

  WNDCLASSEX wc;

  wc.cbClsExtra        =0;

  wc.cbSize          =sizeof(WNDCLASSEX);

  wc.cbWndExtra        =0;

  wc.hbrBackground     =(HBRUSH)GetStock(WHITE_BRUSH);

  wc.hCursor          =LoadCursor(NULL,IDC_ARROW);

  wc.hIcon          =LoadIcon(NULL,IDI_APPLICATION);

  wc.hIconSm          =0;

  wc.hInstance       =hInstance;

  wc.lpfnWndProc        =(WNDPROC)MainProc;

  wc.lpszClassName     =szAppName;

  wc.lpszMenuName        =MAKEINTRESOURCE(IDR_MENU1);

  wc.style          =CS_HREDRAW | CS_VREDRAW |

                 CS_LCLKS | CS_OWNDC;

  RegisterClassEx(&wc);

 

  hWnd=CreateWindowEx(0,szAppName,szAppName,WS_OVERLAPPEDWINDOW,

    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

    NULL,NULL,hInstance,NULL);

  hMainWnd=hWnd;

  hIns=hInstance;

//在此處向系統選單中插入選單項

  DoInsertSysMenu();

  ShowWindow(hWnd,nCmdShow);

  UpdateWindow(hWnd);

 

  while(GetMessage(&msg,NULL,0,0))

  {

    TranslateMessage(&msg);

    DispatchMessage(&msg);

  }

  return msg.wParam;

}

LRESULT CALLBACK MainProc(HWND hWnd,UINT message,

              WPARAM wParam,LPARAM lParam)

{

  HDC hdc;

  PAINTSTRUCT ps;

  switch(message)

  {

  case WM_CREATE:

    return 0;

  case WM_PAINT:

    hdc=BeginPaint(hWnd,&ps);

    //do drawing

    EndPaint(hWnd,&ps);

    return 0;

  case WM_RBUTTONDOWN:

//滑鼠在視窗中右鍵被按下時,彈出浮動式選單

    if(DoDispPopupMenu(hWnd,LO(lParam),HIWORD(lParam)))

    return 0;  //函式成功

    else

    break;    //函式呼叫失敗

  case WM_COMMAND:

    switch(LOWORD(wParam))

    {

    case ID_INSERT:

      if(isInsert==0)

      {//插入新的選單項

        DoInsertMenuItem();

      //顯示相關資訊

        DoDispMessage(4);

      }

      break;

    case ID_NEWITEM:

      DoDispMessage(3);

      break;

    case ID_DELETE:

      if(isInsert!=0)

      {//刪除選單項

        DoDeleteMenuItem();

        DoDispMessage(5);

      }

      break;

    case XIT:

      PostQuitMessage(0);

      break;

    case ID_CHECK:  //在選單選項前打鉤

      DoCheckMenuItem();

      break;

    case ID_RADIO1:  //在選單選項前做一圓形標誌,表明此項被選中,

          //並清除舊的標誌

      idRadio=2;

      DoCheckRadio();

      break;

    case ID_RADIO2:  //同上

      idRadio=3;

      DoCheckRadio();

      break;

    case ID_RADIO3:  //同上

      idRadio=4;

      DoCheckRadio();

      break;

    case ID_FLOAT1:  //浮動選單的選項被選中時的處理

      DoDispMessage(0);

      break;

    case ID_FLOAT2:  //同上

      DoDispMessage(1);

      break;

    case ID_FLOAT3:  //同上

      DoDispMessage(2);

      break;

    }

    return 0;

  case WM_CLOSE:

    PostQuitMessage(0);

    return 0;

  }

  return DefWindowProc(hWnd,message,wParam,lParam);

}

BOOL WINAPI DoDispPopupMenu(HWND hWnd,int x,int y)

{

  HMENU hMenu;

  HMENU hPopupMenu;

  POINT pt={x,y};

//從資源中載入選單資源

  hMenu=LoadMenu(hIns,MAKEINTRESOURCE(IDR_MENU2));

//獲得子選單的控制程式碼

  hPopupMenu=GetSubMenu(hMenu,0);

//視窗座標轉化到螢幕座標

  ClientToScreen(hMainWnd,&pt);

//建立浮動選單

  if(TrackPopupMenu(hPopupMenu,TPM_LEFTALIGN | TPM_RIGHTBUTTON,

    pt.x,pt.y,0,hMainWnd,NULL)==FALSE)

    return FALSE;

//使用完畢,回收

  DestroyMenu(hMenu);

  return TRUE;

}

VOID WINAPI DoDispMessage(int id)

{//在選單事件發生時,輸出相應的字串

  HDC hdc;

  char *mess[]={"Command Floating Menuitem 1 ",

          "Command Floating Menuitem 2 ",

          "Command Floating Menuitem 3 ",

          "Command New Menu Item  ",

          "New Item Have Been Inserted ",

          "New Item Have Been Deleted  "};

  InvalidateRect(hMainWnd,NULL,FALSE);

  hdc=GetDC(hMainWnd);

  TextOut(hdc,0,0,mess[id],strlen(mess[id]));

  ReleaseDC(hMainWnd,hdc);

}

VOID WINAPI DoInsertMenuItem()

{//插入選單項

  HMENU hMenu;

  HMENU hPopupMenu;

  MENUITEMINFO info;

//每一個新插入的選單項都必須填寫MENUITEMINFO結構

  info.cbSize      =sizeof(MENUITEMINFO);

  info.fMask      =MFT_STRING | MIIM_DATA | MIIM_ID | MIIM_TYPE;

  info.fType      =MFT_STRING;

  info.fState      =0;

  info.wID      =ID_NEWITEM;

  info.hSubMenu    =NULL;

  info.hbmpChecked  =NULL;

  info.hbmpUnchecked  =NULL;

  info.dwItemData    =ID_NEWITEM;

  info.dwTypeData    ="New Item";

  info.cch      =8;

//獲得已存在選單的控制程式碼

  hMenu=GetMenu(hMainWnd);

//獲得子選單的控制程式碼

  hPopupMenu=GetSubMenu(hMenu,0);

//插入選單項

  InsertMenuItem(hPopupMenu,1,TRUE,&info);

//置插入標誌為1

  isInsert=1;

}

VOID WINAPI DoDeleteMenuItem()

{//刪除選單項

  HMENU hMenu;

  HMENU hPopupMenu;

  hMenu=GetMenu(hMainWnd);

  hPopupMenu=GetSubMenu(hMenu,0);

  RemoveMenu(hPopupMenu,ID_NEWITEM,MF_BYCOMMAND);

  isInsert=0;

}

VOID WINAPI DoCheckMenuItem()

{//此函式先判斷選單項是否被打鉤,若沒有,則做打鉤標記

 //若已有,則刪除打鉤標記

  HMENU hMenu;

  HMENU hPopupMenu;

  hMenu=GetMenu(hMainWnd);

  hPopupMenu=GetSubMenu(hMenu,1);

 

  if(isCheck)

  {

    CheckMenuItem(hPopupMenu,0,MF_BYPOSITION | MF_UNCHECKED);

    isCheck=0;

  }

  else

  {

    CheckMenuItem(hPopupMenu,0,MF_BYPOSITION | MF_CHECKED);

    isCheck=1;

  }

}

VOID WINAPI DoCheckRadio()

{

  HMENU hMenu;

  HMENU hPopupMenu;

  hMenu=GetMenu(hMainWnd);

  hPopupMenu=GetSubMenu(hMenu,1);

  CheckMenuRadioItem(hPopupMenu,2,4,idRadio,MF_BYPOSITION);

}

VOID WINAPI DoInsertSysMenu()

{//在系統選單中插入選單項

  HMENU hSysMenu;

  MENUITEMINFO info;

//獲得系統選單的控制程式碼

  hSysMenu=GetSystemMenu(hMainWnd,FALSE);

  info.cbSize      =sizeof(MENUITEMINFO);

  info.fMask      =MFT_STRING | MIIM_DATA | MIIM_ID | MIIM_TYPE;

  info.fType      =MFT_STRING;

  info.fState      =MFS_DEFAULT;

  info.wID      =ID_NEWSYSITEM;

  info.hSubMenu    =NULL;

  info.hbmpChecked  =NULL;

  info.hbmpUnchecked  =NULL;

  info.dwItemData    =15;

  info.dwTypeData    ="New system Item";

  info.cch      =15;

  InsertMenuItem(hSysMenu,6,TRUE,&info);

}

 

資原始檔中有以下定義

IDR_MENU1 MENU DISCARDABLE

BEGIN

  POPUP "Menu&1"

  BEGIN

  MENUITEM "InsertItemt[I]",  ID_INSERT

  MENUITEM "DeleteItemt[D]",  ID_DELETE

  MENUITEM "&ExittAlt+F4",  IDEXIT

  END

  POPUP "Menu&2"

  BEGIN

  MENUITEM "CheckText",   ID_CHECK

  MENUITEM SEPARATOR

  MENUITEM "Radio1",  ID_RADIO1

  MENUITEM "Radio2",  ID_RADIO2

  MENUITEM "Radio3",  ID_RADIO3

  MENUITEM SEPARATOR

  MENUITEM "About",  ID_ABOUT

  END

END

IDR_MENU2 MENU DISCARDABLE

BEGIN

  POPUP "Test"

  BEGIN

  MENUITEM "Floating Menu Item1",  ID_FLOAT1, MENUBREAK

  MENUITEM "Floating Menu Item2",  ID_FLOAT2

  MENUITEM "Floating Menu Item3",  ID_FLOAT3

  END

END

有任何意見,建議請 to::y_h_zhang@sohu.com">email:y_h_zhang@sohu.com.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1003222/,如需轉載,請註明出處,否則將追究法律責任。

相關文章