2010-04-08 25 views
5

Trong Microsoft Windows, hoạt động này:Làm thế nào để vô hiệu hóa mục menu hệ thống di chuyển?

mnu := GetSystemMenu(h, false); 
EnableMenuItem(mnu, SC_CLOSE, MF_BYCOMMAND or MF_GRAYED); 

Nhưng điều này không làm việc:

mnu := GetSystemMenu(h, false); 
EnableMenuItem(mnu, SC_MOVE, MF_BYCOMMAND or MF_GRAYED); 

Do đó tôi biết làm thế nào để vô hiệu hóa "Close" mục trình đơn hệ thống của một cửa sổ, nhưng không phải là " Di chuyển "mục. Làm thế nào để làm điều đó?

Cập nhật

Tất nhiên một thay thế cho sử dụng chức năng EnableMenuItem rất tốt đẹp, là sử dụng SetMenuItemInfo:

FillChar(info, sizeOf(info), 0); 
    with info do 
    begin 
    cbSize := sizeOf(info); 
    fMask := MIIM_STATE; 
    fState := MFS_GRAYED; 
    end; 
    SetMenuItemInfo(mnu, SC_MOVE, false, info); 

Nhưng điều này lại hoạt động hoàn hảo cho SC_CLOSE, nhưng không phải ở tất cả cho SC_MOVE!

Cập nhật 2

Mặc dù vấn đề được giải quyết theo nghĩa là một mã số lao động đã được phát hiện ra rằng "không được công việc", có thể nói, nó sẽ là thú vị để nghe giả thuyết về nguyên nhân gây ra vấn đề: Tại sao SC_CLOSE hoạt động chứ không phải SC_MOVE?

Trả lời

3

Đó là một chút của một bí ẩn nhưng nó hoạt động nếu bạn sử dụng ModifyMenu hoặc DeleteMenu:

HMENU mnu = GetSystemMenu(hWnd, false); 
    DeleteMenu(mnu, SC_MOVE, MF_BYCOMMAND); 

hay:

HMENU mnu = GetSystemMenu(hWnd, false); 
    MENUITEMINFO info = { sizeof(MENUITEMINFO) }; 
    TCHAR name[256] = _T("Cannot move"); 
    info.fMask = MIIM_TYPE; 
    info.dwTypeData = name; 
    info.cch = sizeof(name)/sizeof(TCHAR); 
    GetMenuItemInfo(mnu, SC_MOVE, false, &info); 
    ModifyMenu(mnu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED, 0, info.dwTypeData); 
+0

Có, cả hai đều hoạt động. Nhưng đầu tiên sẽ thay đổi chú thích của mục bên cạnh việc không gắn nhãn nó, và thứ hai sẽ loại bỏ hoàn toàn mục ... Tôi chỉ muốn vô hiệu hóa nó ... Tất nhiên tôi có thể tra cứu những gì "Di chuyển" được gọi trong địa phương ngôn ngữ và sử dụng tùy chọn đầu tiên, nhưng nó chắc chắn không phải là thẳng như mong muốn. [BTW: Bạn có thể không có nghĩa là "hoặc MF_GRAYED" trong tùy chọn thứ hai.] –

+0

Bạn có thể sử dụng GetMenuInfo() để đọc chuỗi trước khi sửa đổi mục menu. Đừng quên gắn thẻ câu hỏi đúng nếu bạn muốn "hoặc". –

+0

Vâng, đó có lẽ là cách tốt nhất để có được "Di chuyển" trong ngôn ngữ bên phải. Tôi không hoàn toàn chắc chắn về những gì bạn có ý nghĩa bởi nhận xét thứ hai của bạn. Tôi biết sự khác biệt giữa các ngôn ngữ lập trình. Và bởi vì câu hỏi này là về API Windows, nó không liên quan nếu bạn sử dụng Delphi, C, VB, hoặc bất kỳ ngôn ngữ nào khác.Nhưng bạn có thể có nghĩa là DeleteMenu (mnu, SC_MOVE, MF_BYCOMMAND); thay vì DeleteMenu (mnu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); Tôi không hiểu những gì "hoặc MF_GRAYED" (hoặc "| MF_GRAYED") có nghĩa là trong tùy chọn thứ hai. –

4

Nếu bạn phá hủy các mục menu sử dụng DeleteMenu(), bạn sẽ làm cho ứng dụng không thể di chuyển (thậm chí sử dụng con trỏ).

Điều quan trọng là xóa mục tạm thời.

Đầu tiên, lưu chú thích của "Move" mục sử dụng câu lệnh sau:

GetMenuString(hMenu, SC_MOVE, szMoveCaption, MAX_PATH, MF_BYCOMMAND);

Sau đó, loại bỏ các mục từ menu:

RemoveMenu(hMenu, SC_MOVE, MF_BYCOMMAND);

và khi bạn cần mục "Di chuyển" trở lại, chỉ cần sử dụng InsertMenu()

InsertMenu(hMenu, 0, MF_BYPOSITION, SC_MOVE, szMoveCaption);

PS.

Các vấn đề liên quan