不用资源文件的 VC 窗口程序

1.单个文件的windows  VC程序,不用资源文件。在win32模板程序基础上改。

2. 菜单 和 热键 的代码添加

3. 模式对话框的代码添加。 

程序运行界面,最简的win32程序

 

 代码如下,单个文件,比较麻烦的就是对话框。

 

2023-7-10 修改: 模式对话框之前用MSDN中直接写内存的例子创建控件,比较难控制。

可以只创建一个空窗口,然后在InitDialog 中用通常窗口中创建控件的方法。比较方便直观。

LRESULT InputBox2(HINSTANCE hinst, HWND hwndOwner,
    LPTSTR lpszMessage, void* p)
{
    LRESULT ret;
    int  nchar;

    HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPWORD lpw;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
    lpdt = (LPDLGTEMPLATE)hgbl;

    lpdt->style = WS_POPUP | WS_BORDER | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU; //DS_MODALFRAME

    lpdt->cdit = 0;  // number of controls
    lpdt->x = 100;  lpdt->y = 50;
    lpdt->cx = 200; lpdt->cy = 150;

    lpw = (LPWORD)(lpdt + 1);
    *lpw++ = 0;   // no menu
    *lpw++ = 0;   // predefined dialog box class (by default)

    wcscpy((wchar_t*)lpw, L"DialogBoxIndirect");
    nchar = wcslen((wchar_t*)lpw) + 1;
    lpw += nchar;

    GlobalUnlock(hgbl);
    ret = DialogBoxIndirectParam(hinst, (LPDLGTEMPLATE)hgbl, hwndOwner, (DLGPROC)DlgProc, (LPARAM)p);
    GlobalFree(hgbl);
    return ret;
}


#define IDC_EDIT1     1000
#define IDC_BNOK      1001
#define IDC_BNCANCEL  1002

// Mesage handler for about box.
LRESULT CALLBACK DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
    wchar_t str[100];
    static void* p;

    static HWND hWndEdit1;
    static HWND hWndBNOK;
    static HWND hWndBNCANCEL;

    switch (message)
    {
    case WM_INITDIALOG:

        hWndEdit1 = CreateWindow(_T("edit"), NULL,
            WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL,// | ES_READONLY 
            10, 10, 180, 50, hWnd, (HMENU)IDC_EDIT1, hInst, NULL);

        hWndBNOK = CreateWindow(_T("button"), _T("OK"),
            WS_CHILD | WS_VISIBLE | BS_FLAT, 40, 100, 50, 30, hWnd, (HMENU)IDOK, hInst, NULL);
        hWndBNCANCEL = CreateWindow(_T("button"), _T("CANCEL"),
            WS_CHILD | WS_VISIBLE | BS_FLAT, 100, 100, 50, 30, hWnd, (HMENU)IDCANCEL, hInst, NULL);

        //参数只能在INITDIALOG消息中传进,但是没接口传出,先用个静态变量保存指针
        wcscpy(str, (wchar_t*)lParam);
        SetDlgItemText(hWnd, IDC_EDIT1, str);

        p = (void*)lParam;

        return TRUE;
    case WM_SIZE:
        int cxClient, cyClient;

        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);

        MoveWindow(hWndEdit1, 10, 10, 180, 50, TRUE);
        MoveWindow(hWndBNOK, 40, 100, 50, 30, TRUE);
        MoveWindow(hWndBNCANCEL, 100, 100, 50, 30, TRUE);
        break;
    case WM_PAINT:
        break;
    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {

            GetDlgItemText(hWnd, IDC_EDIT1, str, 100);
            str[99] = 0;
            wcscpy((wchar_t*)p, str);

            EndDialog(hWnd, LOWORD(wParam));
            return TRUE;
        }
        break;
    
    }
    return FALSE;
}

 

下面是之前仿MSDN直接写内存创建控件的完整测试程序

// NOT.cpp : 
//

//#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

//#include "resource.h"
#define IDR_MAINFRAME                    128
#define IDD_NOT_DIALOG                    102
#define IDD_ABOUTBOX                    103
#define IDC_NOT                            109
#define IDC_STATIC                        -1

#define IDM_FILE_NEW                     20001
#define IDM_FILE_EXIT                    20002
#define IDM_TEST_TEST1                   20011
#define IDM_TEST_TEST2                   20012
#define IDM_HELP                         20021
#define IDM_ABOUT                         20022

#define MAX_LOADSTRING 100




// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR szTitle[MAX_LOADSTRING] = _T("NOT");                                // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING] = _T("NOT_XGZ_2023");                // The title bar text

//xgz 
HMENU m_hMenu = NULL;
HMENU m_hMenuPopup = NULL;
int   InitMenu();
int OnCreate(HWND, UINT, WPARAM, LPARAM);
int OnPaint(HWND, UINT, WPARAM, LPARAM);
int OnRButtonUp(HWND, UINT, WPARAM, LPARAM);
int OnTest1(HWND, UINT, WPARAM, LPARAM);

HACCEL  InitAccel();


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

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     MSG msg;
    
    HACCEL hAccelTable;
        
    MyRegisterClass(hInstance);

    if (!InitInstance (hInstance, nCmdShow)) 
    {
        return FALSE;
    }

    //hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_NOT);   //WM_SYSCOMMAND
    
    hAccelTable = InitAccel();


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

    return msg.wParam;
}


ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX); 

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(NULL, IDI_APPLICATION); //标准图标
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(NULL, IDI_APPLICATION); //标准图标 

    return RegisterClassEx(&wcex);
}

int   InitMenu()
{
    HMENU hMenu,hMenuPopup;

    hMenu = CreateMenu();
    m_hMenu = hMenu;    //主菜单
    hMenuPopup = CreateMenu();
    AppendMenu(hMenuPopup, MF_STRING, IDM_FILE_NEW, _T("&New"));
    AppendMenu(hMenuPopup, MF_SEPARATOR, 0, NULL);
    AppendMenu(hMenuPopup, MF_STRING, IDM_FILE_EXIT, _T("&Exit"));
    AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup, _T("&File"));  //File
    
    hMenuPopup = CreateMenu();
    m_hMenuPopup = hMenuPopup; //选一个做主程序的右键弹出菜单
    AppendMenu(hMenuPopup, MF_STRING, IDM_TEST_TEST1, _T("&Test1"));
    AppendMenu(hMenuPopup, MF_STRING, IDM_TEST_TEST2, _T("&Test2"));
    AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup, _T("&Test")); //Test

    AppendMenu(hMenu, MF_STRING, IDM_HELP, _T("&Help")); 
    AppendMenu(hMenu, MF_STRING, IDM_ABOUT, _T("&About")); 
        
    return 0;
}

HACCEL  InitAccel()
{
    ACCEL AccelTable[3] = {
        {FVIRTKEY | FCONTROL,    VK_UP,    IDM_TEST_TEST1},
        {FVIRTKEY | FALT,        VK_F2,    IDM_TEST_TEST2},
        0
    };
    HACCEL hAccel = CreateAcceleratorTable(AccelTable, 2);
    return hAccel;
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   InitMenu();
   SetMenu(hWnd, m_hMenu);

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

   return TRUE;
}

#define ID_HELP   150
#define ID_TEXT   200
#define ID_EDIT   1200

LPWORD lpwAlign(LPWORD lpIn)
{
    ULONG ul;

    ul = (ULONG)lpIn;
    ul += 3;
    ul >>= 2;
    ul <<= 2;
    return (LPWORD)ul;
}



LRESULT InputBox(HINSTANCE hinst, HWND hwndOwner,
    LPTSTR lpszMessage, void* p)
{
    HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWORD lpw;
    LPWSTR lpwsz;
    LRESULT ret;
    int nchar;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 2024);
    if (!hgbl)
        return -1;

    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);

    //=====窗体============.
    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU
        | DS_MODALFRAME | WS_CAPTION;
    lpdt->cdit = 4;  // number of controls
    lpdt->x = 100;  lpdt->y = 50;
    lpdt->cx = 200; lpdt->cy = 150;

    lpw = (LPWORD)(lpdt + 1);
    *lpw++ = 0;   // no menu
    *lpw++ = 0;   // predefined dialog box class (by default)

    wcscpy((wchar_t*)lpw, L"DialogBoxIndirect");
    nchar = wcslen((wchar_t*)lpw) + 1;
    lpw += nchar;

    //=======static text =============
    lpw = lpwAlign(lpw); // align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x = 10; lpdit->y = 10;
    lpdit->cx = 180; lpdit->cy = 20;
    lpdit->id = ID_TEXT;  // text identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0082;                         // static class
        
    lpwsz = (LPWSTR)lpw;
    wcscpy((wchar_t*)lpw, lpszMessage); //初始化字符串
    nchar = wcslen((wchar_t*)lpw) + 1;
    lpw += nchar;

    lpw = lpwAlign(lpw); // align creation data on DWORD boundary
    *lpw++ = 0;           // no creation data
    
    //====== Edit =================
    lpw = lpwAlign(lpw); 
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x = 10; lpdit->y = 40;
    lpdit->cx = 180; lpdit->cy = 50;
    lpdit->id = ID_EDIT;  // edit identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | ES_LEFT | WS_BORDER | ES_MULTILINE | WS_VSCROLL;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0081;    // Edit class

    lpwsz = (LPWSTR)lpw;
    wcscpy((wchar_t*)lpw, L"Input"); //初始化字符串
    nchar = wcslen((wchar_t*)lpw);  //XGZ 这里不能 +1,末尾的0被去掉了???
    lpw += nchar;
    
    lpw = lpwAlign(lpw); 
    *lpw++ = 0;           

    //========= OK button.==============
    lpw = lpwAlign(lpw); 
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x = 80; lpdit->y = 120;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = IDOK;  // OK button identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;    // button class

    lpwsz = (LPWSTR)lpw;
    wcscpy((wchar_t*)lpw, L"OK");
    nchar = wcslen((wchar_t*)lpw) + 1;
    lpw += nchar;
    lpw = lpwAlign(lpw); // align creation data on DWORD boundary
    *lpw++ = 0;           // no creation data

    //======CANCEL button.=========
    lpw = lpwAlign(lpw); 
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x = 140; lpdit->y = 120;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = IDCANCEL;  // CANCEL button identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;    // button class

    lpwsz = (LPWSTR)lpw;
    wcscpy((wchar_t*)lpw, L"CANCEL");
    nchar = wcslen((wchar_t*)lpw) + 1;
    lpw += nchar;
    lpw = lpwAlign(lpw); 
    *lpw++ = 0;           

    GlobalUnlock(hgbl);
    //ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE)hgbl,hwndOwner, (DLGPROC)About);
    //用带参数的方便扩展    
    ret = DialogBoxIndirectParam(hinst, (LPDLGTEMPLATE)hgbl,hwndOwner, (DLGPROC)About, (LPARAM)p);
    GlobalFree(hgbl);
    return ret;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;

    wchar_t p[100] = _T("This is a test");
    
    
    switch (message) 
    {
        case WM_CREATE:
            OnCreate(hWnd, message, wParam, lParam);
            break;
        case WM_PAINT:
            OnPaint(hWnd, message, wParam, lParam);
            break;
        case WM_RBUTTONUP:
            OnRButtonUp(hWnd, message, wParam, lParam);
            break;
        case WM_COMMAND:
            wmId    = LOWORD(wParam); 
            wmEvent = HIWORD(wParam); 
            // Parse the menu selections:
            switch (wmId)
            {
                case IDM_TEST_TEST1:
                    OnTest1(hWnd, message, wParam, lParam);
                    break;
                case IDM_HELP:
                    
                    break;
                case IDM_ABOUT:
                   //DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
                    InputBox(hInst, hWnd, _T("This is a DialogBoxIndirectParam sample."), (void*)p);
                    MessageBox(NULL, p, _T("Input"), MB_OK);
                                      
                   break;
                case IDM_FILE_EXIT:
                   DestroyWindow(hWnd);
                   break;
                default:
                   return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

int OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return 0;
}
int OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    hdc = BeginPaint(hWnd, &ps);
    // TODO: Add any drawing code here...
    RECT rt;
    GetClientRect(hWnd, &rt);
    DrawText(hdc, _T("NOT"), lstrlen(_T("NOT")), &rt, DT_CENTER);
    EndPaint(hWnd, &ps);
    
    return 0;
}

int OnRButtonUp(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    POINT point;

    //point.x = LOWORD(lParam);
    //point.y = LOWORD(lParam);
    //ClientToScreen(hWnd, &point);  //xgz 位置不对 ???

    GetCursorPos(&point);  //xgz 直接取屏幕坐标
    TrackPopupMenu(m_hMenuPopup, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL);

    return 0;
}

int OnTest1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc = GetDC(hWnd);
    TCHAR* p = _T("Test1");
    TextOut(hdc, 10, 10, p, lstrlen(p));
    ReleaseDC(hWnd, hdc);
    return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND hWndEdit;
    wchar_t str[100];
    static void* p;
    
    switch (message)
    {
        case WM_INITDIALOG:

            //参数只能在INITDIALOG消息中传进,但是没接口传出,先用个静态变量保存指针
            wcscpy(str, (wchar_t*) lParam);
            SetDlgItemText(hDlg, ID_EDIT, str);
                
            p = (void*)lParam;
            return TRUE;
                
        case WM_PAINT:
            break;
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
            {
                hWndEdit = GetDlgItem(hDlg, ID_EDIT);
                GetDlgItemText(hDlg, ID_EDIT, str, 100);
                str[99] = 0;
                wcscpy((wchar_t*)p, str);

                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
            }
            break;
    }
    return FALSE;
}

 

posted @ 2023-07-09 16:31  XGZ21  阅读(51)  评论(0编辑  收藏  举报