2017-02-16 19 views
-1

Я создал поле редактирования и список. Когда они перекрываются, с верхним списком курсора мыши меняется на I-Beam, когда он находится над частью списка, который покрывает часть поля редактирования, и появляется схема окна редактирования:Как сохранить контроль над редактированием при закрытии другого элемента управления?

ДО мыши над:

Before mouse over

ПОСЛЕ мыши на:

enter image description here

Код, используемый для создания элементов управления:

HWND hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "xxx", WS_CHILD | WS_VISIBLE| ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 
     50, 100, 200, 100, hWnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL); 

    HWND hList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, _T(""), WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_EDITLABELS, 
     70, 150, 200, 100, hWnd, (HMENU)ID_LIST_VIEW, GetModuleHandle(NULL), NULL); 

Я пытался возиться с й-го порядка с использованием SetWindowPos, но это не меняет поведение. В любом случае, я думаю, что создание контрольного заказа должно помещать список над элементом управления редактированием.

Почему это делается и что еще более важно, как я могу его исправить, поэтому редактирование остается закрытым?

Чтобы воспроизвести, создайте проект win32 в VS2015. Добавьте вышеприведенные 2 строки в WM_CREATE вместе с соответствующими включениями и т. Д. Это в значительной степени. Код ниже без элементов, добавленных в listview.

UPDATE: По многочисленным просьбам здесь полный код:

#include "stdafx.h" 
#include "Win32Project3.h" 
#include <commctrl.h> 

#define MAX_LOADSTRING 100 
#define IDC_MAIN_EDIT 140 
#define ID_LIST_VIEW 143 

#pragma comment(lib, "comctl32.lib") 
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 

#define MAX_LOADSTRING 100 

// Global Variables: 
HINSTANCE hInst;        // current instance 
WCHAR szTitle[MAX_LOADSTRING];     // The title bar text 
WCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name 

// Forward declarations of functions included in this code module: 
ATOM    MyRegisterClass(HINSTANCE hInstance); 
BOOL    InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, 
       _In_opt_ HINSTANCE hPrevInstance, 
       _In_ LPWSTR lpCmdLine, 
       _In_ int  nCmdShow) 
{ 
    UNREFERENCED_PARAMETER(hPrevInstance); 
    UNREFERENCED_PARAMETER(lpCmdLine); 

    // Initialize global strings 
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
    LoadStringW(hInstance, IDC_WIN32PROJECT3, szWindowClass, MAX_LOADSTRING); 
    MyRegisterClass(hInstance); 

    // Perform application initialization: 
    if (!InitInstance (hInstance, nCmdShow)) 
    { 
     return FALSE; 
    } 

    HACCEL hAccelTable = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_WIN32PROJECT3)); 

    MSG msg; 

    // Main message loop: 
    while (GetMessage(&msg, nullptr, 0, 0)) 
    { 
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 
    return (int) msg.wParam; 
} 

ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
    WNDCLASSEXW wcex; 
    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style   = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = WndProc; 
    wcex.cbClsExtra  = 0; 
    wcex.cbWndExtra  = 0; 
    wcex.hInstance  = hInstance; 
    wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT3)); 
    wcex.hCursor  = LoadCursor(nullptr, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WIN32PROJECT3); 
    wcex.lpszClassName = szWindowClass; 
    wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 

    return RegisterClassExW(&wcex); 
} 

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
    hInst = hInstance; // Store instance handle in our global variable 
    HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); 

    if (!hWnd) 
    { 
     return FALSE; 
    } 

    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 

    return TRUE; 
} 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
    case WM_CREATE: 
    { 
     HWND hList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTBOX, _T(""), WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_EDITLABELS, 
     70, 150, 200, 100, hWnd, (HMENU)ID_LIST_VIEW, GetModuleHandle(NULL),NULL); 

     HWND hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, _T("xxx"), WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 
     50, 100, 200, 160, hWnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL); 
    } 
    case WM_COMMAND: 
     { 
      int wmId = LOWORD(wParam); 
      // Parse the menu selections: 
      switch (wmId) 
      { 
      case IDM_ABOUT: 
       DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 
       break; 
      case IDM_EXIT: 
       DestroyWindow(hWnd); 
       break; 
      default: 
       return DefWindowProc(hWnd, message, wParam, lParam); 
      } 
     } 
     break; 
    case WM_PAINT: 
     { 
      PAINTSTRUCT ps; 
      HDC hdc = BeginPaint(hWnd, &ps); 
      EndPaint(hWnd, &ps); 
     } 
     break; 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     break; 
    default: 
     return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    return 0; 
} 
+1

Um ... Не перекрывайте элементы управления? Комбобокс обычно совпадает с сочетанием редактирования и списка. –

+0

Или используйте 'ShowWindow()', чтобы скрыть один элемент управления и показать другой. –

+0

Я не хочу скрывать контроль. Остановите управление редактированием только с помощью элементов управления, которые находятся поверх него. Часть редактирования, которая не покрыта, должна оставаться видимой. – poby

ответ

1

Эффект вызывается один контроль рендеринг в клиентской области другого элемента управления, как это обработка WM_PAINT сообщений.

Чтобы предотвратить это, рендеринг необходимо обрезать, чтобы исключить области, которые заняты другими элементами управления. Установка WS_CLIPSIBLINGSwindow style на управлении инструктирует систему, чтобы применить соответствующую вырезанную область:

Clips дочерних окна по отношению друг к другу; то есть, когда конкретное дочернее окно принимает сообщение WM_PAINT, стиль WS_CLIPSIBLINGS скрепляет все другие перекрывающиеся дочерние окна из области дочернего окна, которое необходимо обновить. Если WS_CLIPSIBLINGS не указывается, а дочерние окна перекрываются, при рисовании внутри клиентской области дочернего окна можно рисовать внутри клиентской области соседнего дочернего окна.