ventana tamaño mostrar letra hacer errores dev consola como cambiar barra c++ windows winapi resize paint

mostrar - WinAPI C++: Cambiar el tamaño de la ventana de reprogramación



tamaño de la consola en c (5)

Este tipo de código se pone feo a toda prisa, está cambiando la posición relativa del mouse al cambiar la posición del área del cliente. Eso requiere que actualice la variable * track_start * cuando ignora el movimiento del mouse cuando la ventana se vuelve demasiado pequeña. No hacerlo produce un efecto, ejem, interesante con la ventana saltando hacia adelante y hacia atrás. Sí, "se retuerce".

Simplemente no lo hagas de esta manera, la característica que estás buscando ya está implementada. Escriba un controlador de mensajes para WM_GETMINMAXINFO . Primero llame a DefWindowProc () y luego anule el valor de MINMAXINFO.ptMinTrackSize. Si la intención es implementar arrastre de esquina o borde en una ventana sin márgenes, implemente un manejador de mensajes para WM_NCHITTEST . Eso también le permite implementar su BORDERWIDTH. La misma receta, llame a DefWindowProc () primero, anule el valor de retorno cuando corresponda.

Tengo una ventana, y quiero implementar los bordes como cambiar el tamaño de los bordes, como cualquier otra ventana. Tomando sugerencias de comentarios y respuestas, he reescrito mi código. Para WM_GETMINMAXINFO tengo:

MINMAXINFO *min_max = reinterpret_cast<MINMAXINFO *>(lparam); min_max->ptMinTrackSize.x = MINX; min_max->ptMinTrackSize.y = MINY;

MINX y MINY son el tamaño mínimo que quiero que tenga la ventana. Para WM_NCHITTEST tengo:

RECT wnd_rect; int x, y; GetWindowRect (window, &wnd_rect); x = GET_X_LPARAM (lparam) - wnd_rect.left; y = GET_Y_LPARAM (lparam) - wnd_rect.top; if (x >= BORDERWIDTH && x <= wnd_rect.right - wnd_rect.left - >BORDERWIDTH && y >= BORDERWIDTH && y <= TITLEBARWIDTH) return HTCAPTION; else if (x < BORDERWIDTH && y < BORDERWIDTH) return HTTOPLEFT; else if (x > wnd_rect.right - wnd_rect.left - BORDERWIDTH && y < BORDERWIDTH) return HTTOPRIGHT; else if (x > wnd_rect.right - wnd_rect.left - BORDERWIDTH && y > wnd_rect.bottom - wnd_rect.top - BORDERWIDTH) return HTBOTTOMRIGHT; else if (x < BORDERWIDTH && y > wnd_rect.bottom - wnd_rect.top - BORDERWIDTH) return HTBOTTOMLEFT; else if (x < BORDERWIDTH) return HTLEFT; else if (y < BORDERWIDTH) return HTTOP; else if (x > wnd_rect.right - wnd_rect.left - BORDERWIDTH) return HTRIGHT; else if (y > wnd_rect.bottom - wnd_rect.top - BORDERWIDTH) return HTBOTTOM; return HTCLIENT;

Las variables son bastante auto explicativas. Este código me da un borde que puedo arrastrar para cambiar el tamaño de la ventana. Funciona bien cuando arrastro los bordes inferior derecho, inferior y derecho. Con las otras fronteras, la esquina inferior derecha de la ventana parece moverse hacia adelante y hacia atrás cuando intento arrastrarlas. Es similar a lo que se ve en Google Chrome o Visual Studio 2012 con el mismo conjunto de bordes, pero no veo esto en el Explorador de Windows.

¿Hay alguna manera de hacer que la esquina inferior derecha no "se mueva" hacia adelante y hacia atrás mientras cambio el tamaño de los bordes superior o izquierdo, como en el Explorador de Windows?


Sería útil ver su código que está cambiando el tamaño y la posición de la ventana.

Cuando mueve los lados inferior o derecho, solo está cambiando el tamaño de la ventana (alto o ancho). Cuando mueve los lados superior o izquierdo, debe cambiar no solo el tamaño sino también la posición de la esquina superior / izquierda.

Si alguien quiere mover el borde izquierdo a la derecha en 10 píxeles, entonces debe aumentar la posición de la esquina en 10 y reducir el ancho en 10, preferiblemente al mismo nivel (por ejemplo, usar SetWindowPos para ambos cambios al mismo tiempo).

Tenga en cuenta que cambiar la posición de esa esquina también cambia la forma en que se interpretan las coordenadas de la pantalla del mouse. Por lo tanto, cualquier almacenamiento de la posición anterior también debería actualizarse.


Lo único que necesita es procesar el mensaje WM_NCCALCSIZE , aumentar el rectángulo rgrc izquierdo con el ancho del borde e incrementar la parte superior con la altura de la barra de subtítulos, y disminuir la derecha con el ancho del borde y la parte inferior con la altura de la barra de subtítulos. Para la esquina de borde debe cambiar la región de su ventana en el mensaje WM_SIZE .


Por desgracia, esta no es la respuesta que estás esperando. En Windows Seven, mover y dimensionar al mismo tiempo una ventana de nivel superior con estilo WS_POPUP está rota. visualmente, la ventana se mueve primero y luego se dimensiona. Al dimensionar por la izquierda o la parte superior, la operación de movimiento revela brevemente los píxeles de fondo, lo que resulta en una experiencia de usuario muy mala.

Hasta donde entiendo lo que está pasando, no tiene nada que ver con WM_GETMINMAXINFO o WM_NCCALCSIZE.

Es muy simple ver el efecto: crea un WS_POPUP | Ventana WS_VISIBLE con un procedimiento de ventana casi vacío, establecer un temporizador y en WM_TIMER usar SetWindowPos, moviendo la ventana un poco hacia la izquierda mientras se dimensiona más grande, para dejar el borde derecho en el mismo lugar. Verás píxeles de fondo, lo cual es una tontería. No hay tal rotura en Windows XP.

Probé muchos trucos, algunos muy retorcidos, pero el resultado final es siempre el mismo: en el momento en que la ventana finalmente se renderiza en su nuevo estado, primero hay una operación de movimiento, luego una talla uno ...

Te quedan 2 opciones (si apuntas a Seven +):

1) Use un borde de tamaño estándar y aproveche las nuevas API (p. Ej .: DwmExtendFrameIntoClientArea) para personalizar el marco según sus necesidades. Vea Marco de ventana personalizado usando DWM en http://msdn.microsoft.com/en-us/library/windows/desktop/bb688195.aspx

2) No use WS_POPUP, sino WS_BORDER y use trucos que engañarán a Windows NUNCA renderizará los bordes. Parece que eso es lo que VS2012 está haciendo.

No lo olvides: el parpadeo DENTRO de la ventana es otra historia, solo estoy hablando de la "estabilidad" del borde derecho / inferior aquí.


Sé que es un poco tarde, pero creo que he encontrado una forma de cambiar el tamaño sin "retorcerme" (el retraso en el dibujo de la ventana interior aún se mantendrá).

A diferencia de lo que ha dicho manuell, WM_NCCALCSIZE es la raíz de todo mal. Además, este método debería funcionar con cualquier estilo de ventana (probado con WS_POPUP y WS_OVERLAPPEDWINDOW ) mientras se preserva su funcionalidad, por lo que es hora de que me calle y publique el código con comentarios:

//some sizing border definitions #define MINX 200 #define MINY 200 #define BORDERWIDTH 5 #define TITLEBARWIDTH 30 //................ HWND TempHwnd = Create(NULL, TEXT("CUSTOM BORDER"), TEXT("CUSTOM BORDER"), WS_POPUP | WS_VISIBLE, 100, 100, 400, 400, NULL, NULL, GetModuleHandle(NULL), NULL); //............... LRESULT CALLBACK WinMsgHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SIZING: // I use this message to redraw window on sizing (o rly?) RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_INTERNALPAINT); return DefWindowProc(hWnd, uMsg, wParam, lParam); case WM_PAINT: // Used to draw borders and stuff to test WM_NCHITTEST { PAINTSTRUCT ps; BeginPaint(hWnd, &ps); RECT ClientRect; GetClientRect(hWnd, &ClientRect); RECT BorderRect = { BORDERWIDTH, BORDERWIDTH, ClientRect.right - BORDERWIDTH - BORDERWIDTH, ClientRect.bottom - BORDERWIDTH - BORDERWIDTH }, TitleRect = { BORDERWIDTH, BORDERWIDTH, ClientRect.right - BORDERWIDTH - BORDERWIDTH, TITLEBARWIDTH }; HBRUSH BorderBrush = CreateSolidBrush(0x0000ff); FillRect(ps.hdc, &ClientRect, BorderBrush); FillRect(ps.hdc, &BorderRect, GetSysColorBrush(2)); FillRect(ps.hdc, &TitleRect, GetSysColorBrush(1)); DeleteObject(BorderBrush); EndPaint(hWnd, &ps); } break; case WM_GETMINMAXINFO: // It is used to restrict WS_POPUP window size { // I don''t know if this works on others MINMAXINFO *min_max = reinterpret_cast<MINMAXINFO *>(lParam); min_max->ptMinTrackSize.x = MINX; min_max->ptMinTrackSize.y = MINY; } break; case WM_CREATE: // In this message we use MoveWindow to invoke { //WM_NCCALCSIZE msg to remove border CREATESTRUCT *WindowInfo = reinterpret_cast<CREATESTRUCT *>(lParam); MoveWindow(hWnd, WindowInfo->x, WindowInfo->y, WindowInfo->cx - BORDERWIDTH, WindowInfo->cy - BORDERWIDTH, TRUE); //Notice that "- BORDERWIDTH" is recommended on every manually called resize function, //Because we will add BORDERWIDTH value in WM_NCCALCSIZE message } break; case WM_NCCALCSIZE: { // Microsoft mentioned that if wParam is true, returning 0 should be enough, but after MoveWindow or similar functions it would begin to "wriggle" if (wParam) { NCCALCSIZE_PARAMS *Params = reinterpret_cast<NCCALCSIZE_PARAMS *>(lParam); Params->rgrc[0].bottom += BORDERWIDTH; // rgrc[0] is what makes this work, don''t know what others (rgrc[1], rgrc[2]) do, but why not change them all? Params->rgrc[0].right += BORDERWIDTH; Params->rgrc[1].bottom += BORDERWIDTH; Params->rgrc[1].right += BORDERWIDTH; Params->rgrc[2].bottom += BORDERWIDTH; Params->rgrc[2].right += BORDERWIDTH; return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } break; case WM_NCHITTEST: { RECT WindowRect; int x, y; GetWindowRect(hWnd, &WindowRect); x = GET_X_LPARAM(lParam) - WindowRect.left; y = GET_Y_LPARAM(lParam) - WindowRect.top; if (x >= BORDERWIDTH && x <= WindowRect.right - WindowRect.left - BORDERWIDTH && y >= BORDERWIDTH && y <= TITLEBARWIDTH) return HTCAPTION; else if (x < BORDERWIDTH && y < BORDERWIDTH) return HTTOPLEFT; else if (x > WindowRect.right - WindowRect.left - BORDERWIDTH && y < BORDERWIDTH) return HTTOPRIGHT; else if (x > WindowRect.right - WindowRect.left - BORDERWIDTH && y > WindowRect.bottom - WindowRect.top - BORDERWIDTH) return HTBOTTOMRIGHT; else if (x < BORDERWIDTH && y > WindowRect.bottom - WindowRect.top - BORDERWIDTH) return HTBOTTOMLEFT; else if (x < BORDERWIDTH) return HTLEFT; else if (y < BORDERWIDTH) return HTTOP; else if (x > WindowRect.right - WindowRect.left - BORDERWIDTH) return HTRIGHT; else if (y > WindowRect.bottom - WindowRect.top - BORDERWIDTH) return HTBOTTOM; else return HTCLIENT; } break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; }