Шаблоны диалогов имеют очень специфический формат и требуют выравнивания DWORD
.Ваша реализация неверна и, вероятно, вызывает неопределенное поведение.
Более простое решение - использовать редактор ресурсов для создания диалога и просто вызвать DialogBox(hinstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, DialogProc)
.Этот метод намного проще, универсальнее и безопаснее.
По умолчанию для элемента управления редактирования установлено ограничение в 32 КБ.Этот предел не изменяется в приведенном выше примере, поэтому неясно, как вы вставляете 1 МБ.
Элемент управления Edit автоматически обрабатывает сообщение WM_PASTE
, если оно имеет фокус.Если элемент управления для редактирования не имеет фокуса, то WM_PASTE
отправляется в диалоговое окно, вы можете просто передать WM_PASTE
в элемент управления для редактирования.
SetWindowLongPtr
является устаревшим методом для элементов управления подклассами.Вместо этого используйте SetWindowSubclass
.
Попробуйте пример ниже.Я снова использовал метод шаблона диалога, но настоятельно рекомендуется использовать редактор ресурсов.Этот код должен быть скомпилирован в Unicode.
//#define UNICODE
#include <Windows.h>
#include <stdio.h>
#include <CommCtrl.h>
//adding library (Visual Studio specific)
#pragma comment(lib, "comctl32.lib")
#define ID_EDIT 200
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
UINT_PTR, DWORD_PTR)
{
switch(msg)
{
case WM_PASTE:
{
if(!IsClipboardFormatAvailable(CF_UNICODETEXT)) break;
if(!OpenClipboard(hwnd)) break;
HANDLE hdata = GetClipboardData(CF_UNICODETEXT);
const wchar_t *lpwszText = (const wchar_t*)GlobalLock(hdata);
SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)lpwszText);
GlobalUnlock(hdata);
CloseClipboard();
return FALSE;
}
case WM_NCDESTROY:
RemoveWindowSubclass(hwnd, EditProc, 0);
return DefSubclassProc(hwnd, msg, wp, lp);
}
return DefSubclassProc(hwnd, msg, wp, lp);
}
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
HWND hedit = GetDlgItem(hwnd, ID_EDIT);
//increase the text limit
SendMessage(hedit, EM_LIMITTEXT, 0x7FFF'FFFF, 0);
//subclass edit control if necessary
SetWindowSubclass(hedit, EditProc, 0, 0);
return TRUE;
}
case WM_COMMAND:
switch(LOWORD(wparam))
{
case IDOK: EndDialog(hwnd, IDOK);
case IDCANCEL: EndDialog(hwnd, IDCANCEL);
}
break;
}
return FALSE;
};
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
{
HGLOBAL hgbl = GlobalAlloc(GMEM_ZEROINIT, 2048);
if(!hgbl)
return -1;
const wchar_t *buf;
int buflen;
DLGITEMTEMPLATE *item;
LPWORD ptr = (LPWORD)GlobalLock(hgbl);
DLGTEMPLATE *dlgtemplate = (DLGTEMPLATE*)ptr;
dlgtemplate->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
dlgtemplate->cdit = 1; /* Number of controls */
dlgtemplate->x = 10;
dlgtemplate->y = 10;
dlgtemplate->cx = 200;
dlgtemplate->cy = 200;
ptr = (LPWORD)(dlgtemplate + 1);
//no menu
*ptr++ = 0;
//predefined dialog box class (by default)
*ptr++ = 0;
//Title
buf = L"Dialog title";
buflen = wcslen(buf);
memcpy(ptr, buf, buflen * sizeof(wchar_t));
ptr += buflen + (buflen % 2);
ptr++;
//-----------------------
// Define a edit control.
//-----------------------
item = (DLGITEMTEMPLATE*)ptr;
item->x = 10;
item->y = 10;
item->cx = 180;
item->cy = 180;
item->id = ID_EDIT;
item->style = WS_BORDER | WS_CHILD | WS_VISIBLE |
ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL;
ptr = (LPWORD)(item + 1);
//edit class
*ptr++ = 0xFFFF;
*ptr++ = 0x0081;
//edit window text not set...
ptr++;
GlobalUnlock(hgbl);
LRESULT ret = DialogBoxIndirect(hInstance, dlgtemplate, NULL, DlgProc);
GlobalFree(hgbl);
return ret;
}