Red de conocimiento informático - Material del sitio web - Cómo integrar la barra de menú y la barra de título en una

Cómo integrar la barra de menú y la barra de título en una

Descubrirás que cada vez más aplicaciones de escritorio combinan la barra de menú y la barra de título en una sola. Para lograr este efecto, generalmente existen dos soluciones:

Dibujar el menú en la barra de título

Eliminar la barra de título y usar la barra de menú como título

Aquí, hablemos brevemente sobre el efecto: en la interfaz de la aplicación, la barra de título y la barra de menú se muestran en la misma área. Cuando el usuario hace clic en el área del menú, aparece el menú correspondiente cuando el usuario hace clic en otro espacio en blanco. áreas, es como si hiciera clic en la barra de título (expresión No estoy seguro, pero creo que todos la entienden).

La opción 2 en realidad contiene dos puntos clave: eliminar la barra de título y usar la barra de menú para simular la barra de título

SetWindowPos

WM_NCHITTEST

. A través de esta noticia sabemos que una ventana se subdivide en más de 20 áreas, dos de las cuales son las que nos interesan ahora, HTMENU y HTCAPTION. Ahora viene la idea. Al procesar el mensaje WM_NCHITTEST usted mismo, si puede convertir parte del HTMENU devuelto por el sistema a HTCAPTION, ¿puede lograr el efecto de simular la barra de título? Los hechos nos dicen que básicamente lo hemos logrado. El código es el siguiente: 1:UINT Cls_OnNCHitTest(HWND hwnd,

intx,

inty)2:{3:UINT uNcHitResult = FORWARD_WM_NCHITTEST(hwnd, x, y, DefWindowProc) ;4: 5:if(HTMENU == uNcHitResult)6:{7:HMENU hMenu = GetMenu(hwnd);8:intnMenuItemCount = GetMenuItemCount(hMenu);9:10:RECT rcTheLastMenu = { 0, 0, 0, 0 } ;11: if(GetMenuItemRect(hwnd, hMenu, nMenuItemCount - 1, &rcTheLastMenu))12:{13:// Al hacer clic en el área en blanco del menú, simula el comportamiento de la barra de título 14:if(rcTheLastMenu. right < x)15:{16: uNcHitResult = HTCAPTION;17:}18:}19:}20:21:returnuNcHitResult;22:}

Después de dicho procesamiento, haga clic/doble clic en el área en blanco de la barra de menú, arrastrar, etc. todo parece Es lo mismo que operar la barra de título.

Después de escribir estos códigos, encontrará varios problemas:

No puede ver el menú del sistema cuando hace clic derecho en el área en blanco de la barra de menú

Pantalla completa después de maximizar, la ventana cubre la barra de tareas

Por lo tanto, este método de simulación solo realiza básicamente la función y no cumple completamente con los requisitos. Ahora resolvamos estos problemas paso a paso. Mire primero el menú del sistema.

intx,

int

y, UINT codeHitTest)2:{3:if(HTCAPTION == codeHitTest)4:{5:HMENU hSysMenu = GetSystemMenu (hwnd,

FALSE);6:intnMenuAlign = GetSystemMetrics(SM_MENUDROPALIGNMENT);7:8:// Preste especial atención a TPM_RETURNCMD, necesitamos saber en qué elemento del menú del sistema hizo clic el usuario 9:BOOL bRes = TrackPopupMenuEx(hSysMenu, nMenuAlign | TPM_RETURNCMD, x, y, hwnd, NULL);10:returnFORWARD_WM_SYSCOMMAND(hwnd, bRes, x, y, DefWindowProc);11:}12:13:FORWARD_WM_NCRBUTTONUP(hwnd, x, y, codeHitTest, DefWindowProc );14:}

Hasta ahora, parece que hemos resuelto todos los problemas del menú. Pero, de hecho, todavía hay un problema. Parece que hay algún problema con el estado de los elementos del menú del sistema. Para resolver este problema, necesitamos usar el mensaje WM_INITMENU para desafiar el estado del elemento de menú correspondiente a través del estado maximizado o minimizado de la ventana actual.

Mire el código: 1: voidCls_OnInitMenu(HWND hwnd, HMENU hMenu)2:{3:if(GetSystemMenu(hwnd,

FALSE) == hMenu)4:{5:UINT uSysCmds[] = {SC_SIZE, SC_MOVE, SC_MINIMIZE, SC_MAXIMIZE, SC_CLOSE, SC_RESTORE};6:if(IsIconic(hwnd))7:{8:for(inti = 0; i < _countof(uSysCmds); ++i)9:{10: switch( uSysCmds[i])11:{12:caseSC_MAXIMIZE:13:caseSC_RESTORE:14:caseSC_CLOSE:15:EnableMenuItem(hMenu, uSysCmds[i], MF_ENABLED);16:break;17:18:default:19:EnableMenuItem( hMenu, uSysCmds[i], MF_DISABLED | MF_GRAYED);20:break;21:}22:}23:}24:elseif(IsZoomed(hwnd))25:{26:for(inti = 0; i < _countof(uSysCmds ++i)27:{28:switch(uSysCmds[i])29:{30:caseSC_RESTORE:31:caseSC_MINIMIZE:32:caseSC_CLOSE:33:EnableMenuItem(hMenu, uSysCmds[i], MF_ENABLED);34:break); ;35 :36:predeterminado:37:EnableMenuItem(hMenu, uSysCmds[i], MF_DISABLED | MF_GRAYED);38:break;39:}40:}41:}42:else43:{44:for(inti = 0; i < _countof (uSysCmds); ++i)45:{46:switch(uSysCmds[i])47:{48:caseSC_RESTORE:49:EnableMenuItem(hMenu, uSysCmds[i], MF_DISABLED | MF_GRAYED);50:break;51 :52 :predeterminado:53:EnableMenuItem(hMenu, uSysCmds[i], MF_ENABLED);54:break;55:}56:}57:}58:}59:else60:{61:FORWARD_WM_INITMENU(hwnd, hMenu, DefWindowProc) ;62 :}63:}

Ya está. Por desgracia, parece haber algo mal. Parece que hay algún problema con el estado del menú del sistema que aparece por primera vez. Cuando aparece nuevamente, parece estar correcto. Es culpa de GetSystemMenu. Para resolver este problema, simplemente llame a GetSystemMenu para hacer una copia antes de que se muestre el menú del sistema.

Llegado a este punto, todos los problemas con el menú del sistema deberían estar resueltos. El siguiente paso es solucionar el problema de la pantalla completa.