Win32怎么让一个应用存在多个WndProc(单独的窗口)

末影小末EnderMo 2020-07-23 03:21:49
想让应用内部多一个内置的文本编辑器,直接给它理解成多窗口吧.
但是主窗口(如下图)已近存在了,就是已经把窗口给注册了,那如何再多加一个内置窗口呢?

这是按钮"编辑器"的命令处理
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDC_BUTTON:
MessageBox(NULL, NULL, NULL, NULL);
//打开文本编辑器
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;

目标:点击"编辑器",运行以下代码
下面是文本编辑器的代码(WINAPI)
LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM);
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
int WINAPI TextEdit(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Typer");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = EditProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Typing Program"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static DWORD dwCharSet = DEFAULT_CHARSET;
static int cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
xCaret, yCaret;
static wchar_t* pBuffer = NULL;
HDC hdc;
int x, y, i;
PAINTSTRUCT ps;
TEXTMETRIC tm;

switch (message)
{
case WM_INPUTLANGCHANGE:
dwCharSet = wParam;
// fall through
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));

GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight;

DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
ReleaseDC(hwnd, hdc);
// fall through
case WM_SIZE:
// obtain window size in pixels

if (message == WM_SIZE)
{
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
}
// calculate window size in characters

cxBuffer = max(1, cxClient / cxChar);
cyBuffer = max(1, cyClient / cyChar);

// allocate memory for buffer and clear it

if (pBuffer != NULL)
free(pBuffer);

pBuffer = (TCHAR*)malloc(cxBuffer * cyBuffer * sizeof(TCHAR));

for (y = 0; y < cyBuffer; y++)
for (x = 0; x < cxBuffer; x++)
BUFFER(x, y) = ' ';

// set caret to upper left corner

xCaret = 0;
yCaret = 0;

if (hwnd == GetFocus())
SetCaretPos(xCaret * cxChar, yCaret * cyChar);

InvalidateRect(hwnd, NULL, TRUE);
return 0;

case WM_SETFOCUS:
// create and show the caret
CreateCaret(hwnd, NULL, cxChar, cyChar);
SetCaretPos(xCaret * cxChar, yCaret * cyChar);
ShowCaret(hwnd);
return 0;

case WM_KILLFOCUS:
// hide and destroy the caret
HideCaret(hwnd);
DestroyCaret();
return 0;

case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME:
xCaret = 0;
break;

case VK_END:
xCaret = cxBuffer - 1;
break;

case VK_PRIOR:
yCaret = 0;
break;

case VK_NEXT:
yCaret = cyBuffer - 1;
break;

case VK_LEFT:
xCaret = max(xCaret - 1, 0);
break;

case VK_RIGHT:
xCaret = min(xCaret + 1, cxBuffer - 1);
break;

case VK_UP:
yCaret = max(yCaret - 1, 0);
break;

case VK_DOWN:
yCaret = min(yCaret + 1, cyBuffer - 1);
break;

case VK_DELETE:
for (x = xCaret; x < cxBuffer - 1; x++)
BUFFER(x, yCaret) = BUFFER(x + 1, yCaret);

BUFFER(cxBuffer - 1, yCaret) = ' ';

HideCaret(hwnd);
hdc = GetDC(hwnd);

SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));
TextOut(hdc, xCaret * cxChar, yCaret * cyChar,
&BUFFER(xCaret, yCaret),
cxBuffer - xCaret);

DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
ReleaseDC(hwnd, hdc);
ShowCaret(hwnd);
break;
}
SetCaretPos(xCaret * cxChar, yCaret * cyChar);
return 0;

case WM_CHAR:
for (i = 0; i < (int)LOWORD(lParam); i++)
{
switch (wParam)
{
case '\b': // backspace
if (xCaret > 0)
{
xCaret--;
SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);
}
break;

case '\t': // tab
do
{
SendMessage(hwnd, WM_CHAR, ' ', 1);
} while (xCaret % 8 != 0);
break;
case '\n': // line feed
if (++yCaret == cyBuffer)
yCaret = 0;
break;

case '\r': // carriage return
xCaret = 0;

if (++yCaret == cyBuffer)
yCaret = 0;
break;

case '\x1B': // escape
for (y = 0; y < cyBuffer; y++)
for (x = 0; x < cxBuffer; x++)
BUFFER(x, y) = ' ';

xCaret = 0;
yCaret = 0;

InvalidateRect(hwnd, NULL, FALSE);
break;

default: // character codes
BUFFER(xCaret, yCaret) = (TCHAR)wParam;

HideCaret(hwnd);
hdc = GetDC(hwnd);

SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));
TextOut(hdc, xCaret * cxChar, yCaret * cyChar,
&BUFFER(xCaret, yCaret), 1);
DeleteObject(
SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
ReleaseDC(hwnd, hdc);
ShowCaret(hwnd);

if (++xCaret == cxBuffer)
{
xCaret = 0;
if (++yCaret == cyBuffer)
yCaret = 0;
}
break;
}
}

SetCaretPos(xCaret * cxChar, yCaret * cyChar);
return 0;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));
for (y = 0; y < cyBuffer; y++)
TextOut(hdc, 0, y * cyChar, &BUFFER(0, y), cxBuffer);
DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
...全文
561 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 19 楼 schlafenhamster 的回复:
一个 exe 只要 一个 消息 循环
辛苦你了,但不是这一个意思 因为我把这个窗口单独放在一个头文件里面,意思就是点击"编辑器"按钮的时候,从这个头文件的TextEdit函数显示窗口 不一定要消息循环 从头说起,这是之前一个类似于当前工程的代码 辛苦一下,看一下这个代码吧
int DlgClose(HWND hwndDlg, LPARAM lParam)
{
    POINT pt;
    wchar_t txt[80];
    pt.x = LOWORD(lParam);
    pt.y = HIWORD(lParam);
    wsprintf(txt, L"x=%d;y=%d\n", LOWORD(lParam), HIWORD(lParam));
    OutputDebugString(txt);
    RECT  rc = { 410, 5, 440, 25 };// 这是 bmp 在主窗口的位置 !
    if (PtInRect(&rc, pt))
    {
        return WM_CLOSE;
    }
    return -1;
}
typedef struct tagMMB
{// 
    HWND hWnd;          // handle 

    LPWSTR lpText;     // text 

    LPWSTR lpCaption;  //  title 

    UINT uType;         // style 

} MMB_PARAM;
//
BOOL CALLBACK DialogProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static HBITMAP hBitmap;                  // 1 静态变量
    static HBITMAP hBitmap2;
    static HBITMAP hBitmap3;
    static HFONT hFont;//定义静态字体变量
    BITMAP         bitmap;
    static HWND close;
    HDC hdcMem = NULL;
    static int      bmWidth, bmHeight;       // 2 静态变量
    char txt[40];
    MMB_PARAM* pmmb = (MMB_PARAM*)lParam;
    UNREFERENCED_PARAMETER(lParam);
    switch (uMsg)
    {
    case WM_INITDIALOG:
        SetWindowText(hwndDlg, pmmb->lpCaption);
        SetWindowText(GetDlgItem(hwndDlg, IDC_STATIC), pmmb->lpText);
        //222222

        return TRUE;
    case WM_PAINT:
    {
        HPEN hpen = CreatePen(PS_SOLID,2,RGB(35,35,35));
        HBRUSH br2 = CreateSolidBrush(RGB(35, 35, 35));
        HPEN hpen3 = CreatePen(PS_SOLID, 2, RGB(244, 244, 244));
        HBRUSH br4 = CreateSolidBrush(RGB(244, 244, 244));
        HPEN hpenOld = NULL;
        HDC hdc = NULL;
        HDC hdc2 = NULL;
        PAINTSTRUCT ps;
        hdc = BeginPaint(hwndDlg, &ps);
        HBRUSH br = CreateSolidBrush(RGB(60, 60, 60));
        FillRect(hdc, &ps.rcPaint, br);
        SelectObject(hdc, hpen);
        SelectObject(hdc, br2);
        Rectangle(hdc, 0, 0, 455, 30);
        HPEN hpen2 = CreatePen(PS_SOLID, 2, RGB(203, 109, 119));
        HBRUSH br3 = CreateSolidBrush(RGB(203, 109, 119));
        SelectObject(hdc, hpen2);
        SelectObject(hdc, br3);
        RoundRect(hdc,420, 25 ,440, 5, 1, 1);
        //----------------close
        SelectObject(hdc, hpen3);
        SelectObject(hdc, br4);
        MoveToEx(hdc, 422, 22, NULL);
        LineTo(hdc, 437, 7);
        MoveToEx(hdc, 437, 22, NULL);
        LineTo(hdc, 422, 7);
        //----------------
        ReleaseDC(hwndDlg, hdc);//Over                                             // 12
        EndPaint(hwndDlg, &ps);
        DeleteObject(br2);
        DeleteObject(br);
        HRGN hRgn = NULL;
        RECT rect;
        GetClientRect(hwndDlg, &rect);
        hRgn = CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 6, 6);
        SetWindowRgn(hwndDlg/*窗口句柄*/, hRgn, TRUE);
        return TRUE;
    }
    case WM_CTLCOLORSTATIC:
    {
        if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_STATIC))//2
        {
            SetTextColor((HDC)wParam, RGB(210, 210, 210));
            SetBkMode((HDC)wParam, TRANSPARENT);
        }
        return (INT_PTR)GetStockObject((NULL_BRUSH));//返回一个空画刷(必须)
    }
    case WM_SIZE: //无效但需要存在的代码
    {
        LONG_PTR Style = ::GetWindowLongPtr(hwndDlg, GWL_STYLE);
        Style = Style & ~WS_CAPTION & ~WS_SYSMENU & ~WS_SIZEBOX;
        ::SetWindowLongPtr(hwndDlg, GWL_STYLE, Style);
        return TRUE;
    }
    case WM_LBUTTONDOWN:
    {
        if (DlgClose(hwndDlg, lParam) > 0)
        {
            EndDialog(hwndDlg, 0);
            break;
        }
        // 移动窗口 
        SendMessage(hwndDlg, WM_NCLBUTTONDOWN, HTCAPTION, 0);  //向窗口发送WM_NCLBUTTONDOWN消息,HTCAPTION 标题
        break;
    }
    case WM_COMMAND:
    {
        case IDC_CLOSE:
        {
            EndDialog(hwndDlg, 0);
        }
    }
    case WM_CLOSE:
        EndDialog(hwndDlg, 0);
    }
    return FALSE;
}
//
int TipBox(
    HWND hWnd,          // handle 
    LPWSTR lpText,     // text 
    LPWSTR lpCaption,  // title 
    UINT uType          // style 
)
{
    MMB_PARAM mmb;
    mmb.hWnd = hWnd;
    mmb.lpText = lpText;
    mmb.lpCaption = lpCaption;
    mmb.uType = uType;
    DialogBoxParam((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
        MAKEINTRESOURCE(IDD_TIPBOX), NULL, DialogProc1, (LPARAM)&mmb);
    return -1;
}

#define D_TipBox TipBox
如上的代码 使用TipBox(NULL,"文字","标题",NULL);就可以显示如下窗口了 但是这个是基于对话框的 但我现在想用我13楼发的代码做一个文本编辑器,用一个新的窗口(什么样的都好,但是不要用通用控件,在对话框实现那串代码也好) 可以做出来吗
schlafenhamster 2020-07-27
  • 打赏
  • 举报
回复
一个 exe 只要 一个 消息 循环
  • 打赏
  • 举报
回复
引用 16 楼 schlafenhamster 的回复:
#define WS_VISIBLE 0x10000000L 没有 ? ShowWindow(SW_SHOW);
SW_SHOW还是显示不了 是要把LRESULT换成INT_PTR?
schlafenhamster 2020-07-25
  • 打赏
  • 举报
回复
#define WS_VISIBLE 0x10000000L
没有 ?
ShowWindow(SW_SHOW);
schlafenhamster 2020-07-25
  • 打赏
  • 举报
回复
多了个 while (GetMessage(&msg, NULL, 0, 0))
参考

#include<Windows.h>
#include"iostream"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ExeProc(HWND, UINT, WPARAM, LPARAM);
using namespace std;
//WINAPI 用来说明在Windows中,参数是如何传递的。WinMain 相当于标准语言中的main()入口函数
HWND g_hwnd,g_hWnd; //用变量存放窗口句柄
int g_WinNum=0;

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int nCmdShow)
{

MSG msg; //用一个变量存放消息
WNDCLASS wc,wcg;//窗口类
//1.设计一个窗口类
wc.style = 0; //窗口的样式
wc.lpfnWndProc = (WNDPROC)WndProc; //指向窗口过程函数的指针
wc.cbClsExtra = 0; //窗口类附加数据
wc.cbWndExtra = 0; //窗口附加数据
wc.hInstance = hInstance; //实例句柄
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); //图标句柄
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //鼠标句柄
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //背景句柄
wc.lpszMenuName = NULL; //窗口菜单
wc.lpszClassName = TEXT("MyWndClass"); //窗口类的名字

wcg.style = 0; //窗口的样式
wcg.lpfnWndProc = (WNDPROC)ExeProc; //指向窗口过程函数的指针
wcg.cbClsExtra = 0; //窗口类附加数据
wcg.cbWndExtra = 0; //窗口附加数据
wcg.hInstance = hInstance; //实例句柄
wcg.hIcon = LoadIcon(NULL, IDI_WINLOGO); //图标句柄
wcg.hCursor = LoadCursor(NULL, IDC_ARROW); //鼠标句柄
wcg.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //背景句柄
wcg.lpszMenuName = NULL; //窗口菜单
wcg.lpszClassName = TEXT("MyWindow"); //窗口类的名字
//2.注册窗口类
RegisterClass(&wc);
RegisterClass(&wcg);
//3.创建窗口
g_hwnd = CreateWindow(
TEXT("MyWndClass"), //窗口类的名称
TEXT("Hello SDK Application"), //窗口的标题
WS_OVERLAPPEDWINDOW, //窗口的样式
//窗口的位置(x,y)和大小(下面的均为默认)
CW_USEDEFAULT, //窗口的位置x坐标
CW_USEDEFAULT, //窗口的位置y坐标
CW_USEDEFAULT, //窗口的大小—宽度
CW_USEDEFAULT, //窗口的大小—高度
NULL, //窗口的父窗口句柄
NULL, //窗口菜单句柄
hInstance, //实例句柄
NULL //附加数据
);
//
g_hWnd = CreateWindow(
TEXT("MyWindow"), //窗口类的名称
TEXT("Hello World"), //窗口的标题
WS_OVERLAPPEDWINDOW, //窗口的样式
//窗口的位置(x,y)和大小(下面的均为默认)
CW_USEDEFAULT, //窗口的位置x坐标
CW_USEDEFAULT, //窗口的位置y坐标
CW_USEDEFAULT, //窗口的大小—宽度
CW_USEDEFAULT, //窗口的大小—高度
NULL, //窗口的父窗口句柄
NULL, //窗口菜单句柄
hInstance, //实例句柄
NULL //附加数据
);
//4.显示窗口
ShowWindow(g_hwnd,SW_SHOW);
ShowWindow(g_hWnd,SW_SHOW);
g_WinNum =2;
//5.消息循环
while(TRUE)
{
//int ret=GetMessage(&msg,NULL,0,0);
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{ // test if this is a quit
// if ((ret==0) && (g_WinNum ==0))
if ((msg.message == WM_QUIT) && (g_WinNum ==0))
{
break;
}
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
} // end while
return msg.wParam;
}

//编写窗口过程函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; //绘画结构
HDC hdc; //DC句柄
//对各种消息进行处理
switch (message)
{
case WM_PAINT: //绘制消息
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, "第一个Window", lstrlen("第一个Window"));
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY: //销毁窗口消息(关闭)
g_WinNum--;
PostQuitMessage(0);
break;
case WM_CLOSE: //弹出提示关闭的窗口
if (IDCANCEL == MessageBox(hwnd, "是否关闭第一个窗口?", "提示消息", MB_OKCANCEL | MB_ICONQUESTION))
break;
else
return DefWindowProc(hwnd, message, wParam, lParam);
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}

LRESULT CALLBACK ExeProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; //绘画结构
HDC hdc; //DC句柄
//对各种消息进行处理
switch (message)
{
case WM_PAINT: //绘制消息
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 100, 100, "第二个Window", lstrlen("第二个Window"));
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY: //销毁窗口消息(关闭)
g_WinNum--;
PostQuitMessage(0);
break;
case WM_CLOSE: //弹出提示关闭的窗口
if (IDCANCEL == MessageBox(hWnd, "你真的要关闭第二个窗口?", "提示消息", MB_OKCANCEL | MB_ICONQUESTION))
break;
else
return DefWindowProc(hWnd, message, wParam, lParam);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
点击时 hwnd = CreateWindow(szAppName, TEXT("Typing Program"),。。 就可以了
我将代码单独放置到TextEditor.h里面
HINSTANCE hInstance;
LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM);
typedef struct tagwedit
{// 
    HWND hWnd;          // handle 

    LPWSTR lpText;     // text 

    LPWSTR lpCaption;  //  title 

    UINT uType;         // style 

    int iCmdShow;

} DESEDIT_PARAM;
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
int TextEdit(
    HWND hWnd,          // handle 
    LPWSTR lpText,     // text 
    LPWSTR lpCaption,  // title 
    UINT uType          // style 
)
{
    static TCHAR  szAppName[] = TEXT("Typer");
    DESEDIT_PARAM mmb;
    mmb.hWnd = hWnd;
    mmb.lpText = lpText;
    mmb.lpCaption = lpCaption;
    mmb.iCmdShow = uType;
    hWnd = CreateWindow(szAppName, TEXT("Typing Program"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, uType);
    UpdateWindow(hWnd);
    return -1;
}

/*
int WINAPI TextEdit(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR  szAppName[] = TEXT("Typer");
    HWND                  hwnd;
    MSG                   msg;
    WNDCLASS              wndclass;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = EditProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(szAppName, TEXT("Typing Program"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
*/
LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static DWORD          dwCharSet = DEFAULT_CHARSET;
    static int            cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
        xCaret, yCaret;
    static wchar_t* pBuffer = NULL;
    HDC                           hdc;
    int                           x, y, i;
    PAINTSTRUCT           ps;
    TEXTMETRIC            tm;

    switch (message)
    {
    case   WM_INPUTLANGCHANGE:
        dwCharSet = wParam;
        // fall through
    case   WM_CREATE:
        hdc = GetDC(hwnd);
        SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
            dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));

        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cyChar = tm.tmHeight;

        DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
        ReleaseDC(hwnd, hdc);
        // fall through             
    case  WM_SIZE:
        // obtain window size in pixels

        if (message == WM_SIZE)
        {
            cxClient = LOWORD(lParam);
            cyClient = HIWORD(lParam);
        }
        // calculate window size in characters

        cxBuffer = max(1, cxClient / cxChar);
        cyBuffer = max(1, cyClient / cyChar);

        // allocate memory for buffer and clear it

        if (pBuffer != NULL)
            free(pBuffer);

        pBuffer = (TCHAR*)malloc(cxBuffer * cyBuffer * sizeof(TCHAR));

        for (y = 0; y < cyBuffer; y++)
            for (x = 0; x < cxBuffer; x++)
                BUFFER(x, y) = ' ';

        // set caret to upper left corner

        xCaret = 0;
        yCaret = 0;

        if (hwnd == GetFocus())
            SetCaretPos(xCaret * cxChar, yCaret * cyChar);

        InvalidateRect(hwnd, NULL, TRUE);
        return 0;

    case   WM_SETFOCUS:
        // create and show the caret
        CreateCaret(hwnd, NULL, cxChar, cyChar);
        SetCaretPos(xCaret * cxChar, yCaret * cyChar);
        ShowCaret(hwnd);
        return 0;

    case WM_KILLFOCUS:
        // hide and destroy the caret
        HideCaret(hwnd);
        DestroyCaret();
        return 0;

    case   WM_KEYDOWN:
        switch (wParam)
        {
        case VK_HOME:
            xCaret = 0;
            break;

        case   VK_END:
            xCaret = cxBuffer - 1;
            break;

        case   VK_PRIOR:
            yCaret = 0;
            break;

        case   VK_NEXT:
            yCaret = cyBuffer - 1;
            break;

        case   VK_LEFT:
            xCaret = max(xCaret - 1, 0);
            break;

        case   VK_RIGHT:
            xCaret = min(xCaret + 1, cxBuffer - 1);
            break;

        case   VK_UP:
            yCaret = max(yCaret - 1, 0);
            break;

        case   VK_DOWN:
            yCaret = min(yCaret + 1, cyBuffer - 1);
            break;

        case   VK_DELETE:
            for (x = xCaret; x < cxBuffer - 1; x++)
                BUFFER(x, yCaret) = BUFFER(x + 1, yCaret);

            BUFFER(cxBuffer - 1, yCaret) = ' ';

            HideCaret(hwnd);
            hdc = GetDC(hwnd);

            SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
                dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));
            TextOut(hdc, xCaret * cxChar, yCaret * cyChar,
                &BUFFER(xCaret, yCaret),
                cxBuffer - xCaret);

            DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
            ReleaseDC(hwnd, hdc);
            ShowCaret(hwnd);
            break;
        }
        SetCaretPos(xCaret * cxChar, yCaret * cyChar);
        return 0;

    case   WM_CHAR:
        for (i = 0; i < (int)LOWORD(lParam); i++)
        {
            switch (wParam)
            {
            case '\b':                                           // backspace
                if (xCaret > 0)
                {
                    xCaret--;
                    SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);
                }
                break;

            case '\t':                                                  // tab
                do
                {
                    SendMessage(hwnd, WM_CHAR, ' ', 1);
                } while (xCaret % 8 != 0);
                break;
            case '\n':                                                  // line feed
                if (++yCaret == cyBuffer)
                    yCaret = 0;
                break;

            case '\r':                                                  // carriage return
                xCaret = 0;

                if (++yCaret == cyBuffer)
                    yCaret = 0;
                break;

            case '\x1B':                                       // escape
                for (y = 0; y < cyBuffer; y++)
                    for (x = 0; x < cxBuffer; x++)
                        BUFFER(x, y) = ' ';

                xCaret = 0;
                yCaret = 0;

                InvalidateRect(hwnd, NULL, FALSE);
                break;

            default:                                                    // character codes
                BUFFER(xCaret, yCaret) = (TCHAR)wParam;

                HideCaret(hwnd);
                hdc = GetDC(hwnd);

                SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
                    dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));
                TextOut(hdc, xCaret * cxChar, yCaret * cyChar,
                    &BUFFER(xCaret, yCaret), 1);
                DeleteObject(
                    SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
                ReleaseDC(hwnd, hdc);
                ShowCaret(hwnd);

                if (++xCaret == cxBuffer)
                {
                    xCaret = 0;
                    if (++yCaret == cyBuffer)
                        yCaret = 0;
                }
                break;
            }
        }

        SetCaretPos(xCaret * cxChar, yCaret * cyChar);
        return 0;

    case   WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,
            dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));
        for (y = 0; y < cyBuffer; y++)
            TextOut(hdc, 0, y * cyChar, &BUFFER(0, y), cxBuffer);
        DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
        EndPaint(hwnd, &ps);
        return 0;

    case   WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
TextEdit(hwnd,"","",NULL) 但是没有显示.
schlafenhamster 2020-07-24
  • 打赏
  • 举报
回复
注册还是要的, 否则 CreateWindow 不会成功
  • 打赏
  • 举报
回复
引用 9 楼 schlafenhamster 的回复:
自己写个 edit 不容易, 包括 中英文·
代码已经在帖子上面了,只需要讨论怎么显示这个窗口 那这样的话 如上代码,改为
int Tip TextEdit(
    HWND hWnd,          // handle 
    LPWSTR lpText,     // text 
    LPWSTR lpCaption,  // title 
    UINT uType          // style 
)
{
    MMB_PARAM mmb;
    mmb.hWnd = hWnd;
    mmb.lpText = lpText;
    mmb.lpCaption = lpCaption;
    mmb.uType = uType;
    /*
    DialogBoxParam((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
        MAKEINTRESOURCE(IDD_TIPBOX), NULL, DialogProc1, (LPARAM)&mmb);
*/
    return -1;
}
就是用CreateWindow(szAppName, TEXT("Typing Program") 替换掉DialogParam就可以了吗
schlafenhamster 2020-07-24
  • 打赏
  • 举报
回复
点击时 hwnd = CreateWindow(szAppName, TEXT("Typing Program"),。。
就可以了
schlafenhamster 2020-07-24
  • 打赏
  • 举报
回复
自己写个 edit 不容易, 包括 中英文·
  • 打赏
  • 举报
回复
引用 14 楼 schlafenhamster 的回复:
你把 注册代码 删除了 ? 你可以与主窗口 调试 注册 这个窗口
但是注册后还是显示不了
HINSTANCE hInstance;
LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM);
typedef struct tagwedit
{// 
    HWND hWnd;          // handle 

    LPWSTR lpText;     // text 

    LPWSTR lpCaption;  //  title 

    UINT uType;         // style 

    int iCmdShow;

} DESEDIT_PARAM;
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
int TextEdit(
    HWND hWnd,          // handle 
    LPWSTR lpText,     // text 
    LPWSTR lpCaption,  // title 
    UINT uType          // style 
)
{
    static TCHAR  szAppName[] = TEXT("Typer");
    DESEDIT_PARAM mmb;
    mmb.hWnd = hWnd;
    mmb.lpText = lpText;
    mmb.lpCaption = lpCaption;
    mmb.iCmdShow = uType;
    HWND                  hwnd;
    MSG                   msg;
    WNDCLASS              wndclass;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = EditProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(szAppName, TEXT("Typing Program"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, uType);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
schlafenhamster 2020-07-24
  • 打赏
  • 举报
回复
你把 注册代码 删除了 ?
你可以与主窗口 调试 注册 这个窗口



















  • 打赏
  • 举报
回复
引用 5 楼 zgl7903 的回复:
wndclass.lpfnWndProc = xxxxxxProc; wndclass.lpszClassName = xxxxxx 注册类的时候指定不同的 lpfnWndProc 和 lpszClassName, CreateWindow 的时候用这个注册的类名即可
意思也不是子窗口,是以条件显示的 比如点击按钮才显示 之前就是一个类似的内置窗口例子:
typedef struct tagMMB
{// 
    HWND hWnd;          // handle 

    LPWSTR lpText;     // text 

    LPWSTR lpCaption;  //  title 

    UINT uType;         // style 

} MMB_PARAM;
//
BOOL CALLBACK DialogProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static HBITMAP hBitmap;                  // 1 静态变量
    static HBITMAP hBitmap2;
    static HBITMAP hBitmap3;
    static HFONT hFont;//定义静态字体变量
    BITMAP         bitmap;
    static HWND close;
    HDC hdcMem = NULL;
    static int      bmWidth, bmHeight;       // 2 静态变量
    char txt[40];
    MMB_PARAM* pmmb = (MMB_PARAM*)lParam;
    UNREFERENCED_PARAMETER(lParam);
    switch (uMsg)
    {
    case WM_INITDIALOG:
        SetWindowText(hwndDlg, pmmb->lpCaption);
        SetWindowText(GetDlgItem(hwndDlg, IDC_STATIC), pmmb->lpText);
        //222222
        //Button(hwndDlg,185,170,L"关闭",IDC_CLOSE);
        return TRUE;
    case WM_PAINT:
    {
        HPEN hpen = CreatePen(PS_SOLID,2,RGB(35,35,35));
        HBRUSH br2 = CreateSolidBrush(RGB(35, 35, 35));
        HPEN hpen3 = CreatePen(PS_SOLID, 2, RGB(244, 244, 244));
        HBRUSH br4 = CreateSolidBrush(RGB(244, 244, 244));
        HPEN hpenOld = NULL;
        HDC hdc = NULL;
        HDC hdc2 = NULL;
        PAINTSTRUCT ps;
        hdc = BeginPaint(hwndDlg, &ps);
        HBRUSH br = CreateSolidBrush(RGB(60, 60, 60));
        FillRect(hdc, &ps.rcPaint, br);
        SelectObject(hdc, hpen);
        SelectObject(hdc, br2);
        Rectangle(hdc, 0, 0, 455, 30);
        HPEN hpen2 = CreatePen(PS_SOLID, 2, RGB(203, 109, 119));
        HBRUSH br3 = CreateSolidBrush(RGB(203, 109, 119));
        SelectObject(hdc, hpen2);
        SelectObject(hdc, br3);
        RoundRect(hdc,420, 25 ,440, 5, 1, 1);
        //----------------close
        SelectObject(hdc, hpen3);
        SelectObject(hdc, br4);
        MoveToEx(hdc, 422, 22, NULL);
        LineTo(hdc, 437, 7);
        MoveToEx(hdc, 437, 22, NULL);
        LineTo(hdc, 422, 7);
        //----------------
        ReleaseDC(hwndDlg, hdc);//Over                                             // 12
        EndPaint(hwndDlg, &ps);
        DeleteObject(br2);
        DeleteObject(br);
        HRGN hRgn = NULL;
        RECT rect;
        GetClientRect(hwndDlg, &rect);
        hRgn = CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 6, 6);
        SetWindowRgn(hwndDlg/*窗口句柄*/, hRgn, TRUE);
        return TRUE;
    }
    case WM_CTLCOLORSTATIC:
    {
        if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_STATIC))//2
        {
            SetTextColor((HDC)wParam, RGB(210, 210, 210));
            SetBkMode((HDC)wParam, TRANSPARENT);
        }
        return (INT_PTR)GetStockObject((NULL_BRUSH));//返回一个空画刷(必须)
    }
    case WM_SIZE: //无效但需要存在的代码
    {
        LONG_PTR Style = ::GetWindowLongPtr(hwndDlg, GWL_STYLE);
        Style = Style & ~WS_CAPTION & ~WS_SYSMENU & ~WS_SIZEBOX;
        ::SetWindowLongPtr(hwndDlg, GWL_STYLE, Style);
        return TRUE;
    }
    case WM_LBUTTONDOWN:
    {
        //if (DlgClose(hwndDlg, lParam) > 0)
        //{
            //EndDialog(hwndDlg, 0);
            //break;
        //}
        // 移动窗口 
        SendMessage(hwndDlg, WM_NCLBUTTONDOWN, HTCAPTION, 0);  //向窗口发送WM_NCLBUTTONDOWN消息,HTCAPTION 标题
        break;
    }
    case WM_COMMAND:
    {
        case IDC_CLOSE:
        {
            EndDialog(hwndDlg, 0);
        }
    }
    case WM_CLOSE:
        EndDialog(hwndDlg, 0);
    }
    return FALSE;
}
//
int TipBox(
    HWND hWnd,          // handle 
    LPWSTR lpText,     // text 
    LPWSTR lpCaption,  // title 
    UINT uType          // style 
)
{
    MMB_PARAM mmb;
    mmb.hWnd = hWnd;
    mmb.lpText = lpText;
    mmb.lpCaption = lpCaption;
    mmb.uType = uType;
    DialogBoxParam((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
        MAKEINTRESOURCE(IDD_TIPBOX), NULL, DialogProc1, (LPARAM)&mmb);
    return -1;
}

#define D_TipBox TipBox
调用方法是 TipBox(NULL,"TXT","TITLE",NULL)即可 就是想像这个一样调用 只不过,上面那个是对话框,现在我想创建一个纯窗口而已
  • 打赏
  • 举报
回复
引用 5 楼 zgl7903 的回复:
wndclass.lpfnWndProc = xxxxxxProc; wndclass.lpszClassName = xxxxxx 注册类的时候指定不同的 lpfnWndProc 和 lpszClassName, CreateWindow 的时候用这个注册的类名即可
请问我需要在按下"编辑器"按钮的时候打开这个窗口,该如何做呢?
case IDC_BUTTON:
                MessageBox(NULL, NULL, NULL, NULL);
                //在这里打开文本编辑器
zgl7903 2020-07-23
  • 打赏
  • 举报
回复
wndclass.lpfnWndProc = xxxxxxProc; wndclass.lpszClassName = xxxxxx 注册类的时候指定不同的 lpfnWndProc 和 lpszClassName, CreateWindow 的时候用这个注册的类名即可
  • 打赏
  • 举报
回复
主要是这样
引用 3 楼 schlafenhamster 的回复:
你也可以 用 对话框 (放一个 edit)。点击时 popup 出来
想多注册一个类的原因主要还是 通用对话框限制很大,WM_SIZE之类的消息处理不了,改变难度太大了... 所以才决定自己新创建一个窗体,和WindowProc一样进行改变,绘制. "总之,上面的代码是可以做成一个单独的exe的,只是想把这个代码合并到一个应用里面而已"
schlafenhamster 2020-07-23
  • 打赏
  • 举报
回复
你也可以 用 对话框 (放一个 edit)。点击时 popup 出来
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
怎么又自己 注册 文本编辑器, 了 ? 系统 有edit

HWND m_hEdit=0;
//
HWND CreateEdit(HWND parentWnd)
{
	HWND hEd=0;
	hEd = CreateWindow("EDIT",
                NULL,
                WS_CHILD | WS_TABSTOP | WS_VISIBLE | WS_BORDER ,
                4, 60 ,120, 40, 
                parentWnd, (HMENU)IDC_EDIT, 
                g_hInstance, 
                NULL);
	SetWindowText(hEd,"Gen Create");
//
	return hEd;
}
//
LRESULT CALLBACK EDProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{// get oldproc
	WNDPROC OldEdProc=(WNDPROC)GetProp(hWnd,"EditOldProc");	
    switch (Msg)
    {
		case WM_CREATE:
		break;
	}
	return CallWindowProc(OldEdProc, hWnd, Msg, wParam, lParam);
}
主窗口 点击"编辑器" 时 // m_hEdit=CreateEdit(hwnd); // subclass edit ! WNDPROC EdOldProc = (WNDPROC)SetWindowLong(m_hEdit, GWL_WNDPROC, (LONG)EDProc); SetProp(m_hEdit,// handle of window "EditOldProc", // atom or address of string EdOldProc);
不想用通用控件实现,限制太大了. 总之,上面的代码是可以做成一个单独的exe的,只是想把这个代码合并到一个应用里面而已
schlafenhamster 2020-07-23
  • 打赏
  • 举报
回复
怎么又自己 注册 文本编辑器, 了 ? 系统 有edit


HWND m_hEdit=0;
//
HWND CreateEdit(HWND parentWnd)
{
HWND hEd=0;
hEd = CreateWindow("EDIT",
NULL,
WS_CHILD | WS_TABSTOP | WS_VISIBLE | WS_BORDER ,
4, 60 ,120, 40,
parentWnd, (HMENU)IDC_EDIT,
g_hInstance,
NULL);
SetWindowText(hEd,"Gen Create");
//
return hEd;
}
//
LRESULT CALLBACK EDProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{// get oldproc
WNDPROC OldEdProc=(WNDPROC)GetProp(hWnd,"EditOldProc");
switch (Msg)
{
case WM_CREATE:
break;
}
return CallWindowProc(OldEdProc, hWnd, Msg, wParam, lParam);
}


主窗口 点击"编辑器" 时
//
m_hEdit=CreateEdit(hwnd);
// subclass edit !
WNDPROC EdOldProc = (WNDPROC)SetWindowLong(m_hEdit, GWL_WNDPROC, (LONG)EDProc);
SetProp(m_hEdit,// handle of window
"EditOldProc", // atom or address of string
EdOldProc);


15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧