目前共有13篇帖子。 内容转换:不转换▼
 
点击 回复
364 12
今天,我又把C语言课本上的Insert Str程序做成了Win32版本的对话框程序
一派护法 十九级
1楼 发表于:2015-12-1 23:23
运行效果:

一派护法 十九级
2楼 发表于:2015-12-1 23:25
其中这个InsertStr窗口是通过主窗口的File菜单的Show Dialog...命令(或者按下对应的快捷键Ctrl + O)打开的:

一派护法 十九级
3楼 发表于:2015-12-1 23:26
这是课本上的程序:
void insert(wchar_t *s1, wchar_t *s2)
{
    int f = 0;
    int len1 = wcslen(s1);
    int len2 = wcslen(s2);
    wchar_t *p1 = s1;
    wchar_t *p2 = s1 + len1 - 1;
    while (*p1 != '\0' && *p1 != *s2)
        p1++;
    if (*p1 != '\0')
    {
        for (; p2 > p1; p2--)
            *(p2 + len2 - 1) = *p2;
        f = 1;
    }
    while (*s2)
        *p1++ = *s2++;
    *(s1 + len1 + len2 - f) = '\0';
}
本来是在控制台窗口中运行的,我把它搬到了Windows窗口程序中拿来用。
把所有的char改成wchar_t(宽字符,用于支持中文等双字节字符),strlen改成wcslen,其他的全部照着书上的抄下来。
一派护法 十九级
4楼 发表于:2015-12-1 23:27
在菜单资源中添加一个新菜单项:

Caption: &Show Dialog...\tCtrl+O
ID: ID_FILE_SHOWDIALOG
一派护法 十九级
5楼 发表于:2015-12-1 23:28
打开rc中的快捷键资源IDC_WIN32PROJECT1,添加一个新快捷键Ctrl + O:

ID可以不修改,就用默认的。
一派护法 十九级
6楼 发表于:2015-12-1 23:30
在C++源文件中的WndProc函数中,switch (wmId)下添加如下内容:
case ID_FILE_SHOWDIALOG:
case ID_ACCELERATOR32772:
    DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, Dlg1);
    break;
一派护法 十九级
7楼 发表于:2015-12-1 23:30
创建函数:
INT_PTR CALLBACK Dlg1(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        Dlg1_Init(hDlg);
        return (INT_PTR)TRUE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            Dlg1_GetResult(hDlg);
            break;
        case IDCANCEL:
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

void Dlg1_Init(HWND hDlg)
{
    HWND tf1 = GetDlgItem(hDlg, IDC_EDIT1);
    HWND tf2 = GetDlgItem(hDlg, IDC_EDIT2);
    SendMessage(tf1, WM_SETTEXT, NULL, (LPARAM)L"abcdef");
    SendMessage(tf2, WM_SETTEXT, NULL, (LPARAM)L"d45");
}

void insert(wchar_t *s1, wchar_t *s2)
{
    int f = 0;
    int len1 = wcslen(s1);
    int len2 = wcslen(s2);
    wchar_t *p1 = s1;
    wchar_t *p2 = s1 + len1 - 1;
    while (*p1 != '\0' && *p1 != *s2)
        p1++;
    if (*p1 != '\0')
    {
        for (; p2 > p1; p2--)
            *(p2 + len2 - 1) = *p2;
        f = 1;
    }
    while (*s2)
        *p1++ = *s2++;
    *(s1 + len1 + len2 - f) = '\0';
}

void Dlg1_GetResult(HWND hDlg)
{
    HWND tf1 = GetDlgItem(hDlg, IDC_EDIT1);
    HWND tf2 = GetDlgItem(hDlg, IDC_EDIT2);
    HWND tf3 = GetDlgItem(hDlg, IDC_EDIT3);
    wchar_t s1[100];
    wchar_t s2[100];
    GetWindowText(tf1, s1, 500);
    GetWindowText(tf2, s2, 500);
    insert(s1, s2);
    SendMessage(tf3, WM_SETTEXT, NULL, (LPARAM)s1);
}
一派护法 十九级
8楼 发表于:2015-12-1 23:32
在头文件(Win32Project1.h)添加如下函数声明:
void Dlg1_Init(HWND hDlg);
void insert(wchar_t *s1, wchar_t *s2);
void Dlg1_GetResult(HWND hDlg);

下面这一行可以放到cpp文件的// Forward declarations of functions included in this code module:下面的最后一行:
INT_PTR CALLBACK    Dlg1(HWND, UINT, WPARAM, LPARAM);
当然也可以直接放到头文件中
一派护法 十九级
9楼 发表于:2015-12-1 23:32
(可选)
按下面帖子中所述的方法启用XP风格控件:
https://zh.arslanbar.net/post.php?t=22016
一派护法 十九级
10楼 发表于:2015-12-1 23:33
对话框的布局:

Ctrl + D设置的Tab访问的控件顺序:

一派护法 十九级
11楼 发表于:2015-12-1 23:34
文本框的ID都是默认的:
IDC_EDIT1
IDC_EDIT2
IDC_EDIT3
最后一个文本框要设为只读(Read Only)
一派护法 十九级
12楼 发表于:2015-12-1 23:35
然后就可以运行程序了。

一派护法 十九级
13楼 发表于:2015-12-1 23:44
由于Win32程序是C++语言直接调用Windows API来创建和显示窗口,所以并未使用到微软的MFC类库,也就不涉及到CString字符串类的操作。因此,直接把字符数组通过Windows 消息发送给文本框控件就行了,读取的时候也只需要调用GetWindowText函数把文本框中输入的内容存入字符数组,和scanf几乎完全一样(除了scanf不能传入空格这一点不同以外)

而MFC的CString则不同,通过调用GetBuffer()方法可以获得字符数组指针的缓冲(操作这个字符串指针中的内容就会立刻影响CString字符串的内容),但是这个缓冲的大小是动态变化的,由CString内部决定,所以如果直接通过赋值\0来加长字符串就会导致数组越界而出错。

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:364 回复数:12
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2015-12-1 23:44
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。