使用MASM32+Win32:如何给对话框标题增删文件名路径?
问题描述
我使用Win32的lstrcat指令将对话框标题(AppName)与对话框中打开文件的路径及文件名(ofn.lpstrFile)拼接,再通过SetWindowText修改对话框标题。但遇到两个问题:
- 关闭文件时无法移除标题中的路径与文件名
- 其他消息框的标题和文本也意外被修改
我尝试过的解决思路:
- 拼接前保存
AppName副本,关闭文件时用副本覆盖拼接后的AppName,但会导致原标题和部分路径消失,仍残留部分路径文件名 - 为其他消息框标题使用不同变量名,但仍显示拼接后的字符串
以下是我最新尝试的代码:
ChangeDialogBoxTitle PROC hWnd ; Copy Current Title push esi push edi invoke lstrlen,addr AppName mov ecx,eax LEA esi, AppName LEA edi, AppNameDUP push ds pop es cld rep movsb [edi],[esi] pop edi pop esi ; CLEAR Current Title push esi push edi invoke lstrlen,addr AppName mov ecx,eax LEA esi, BLANK LEA edi, AppName push ds pop es cld rep movsb [edi],[esi] pop edi pop esi ; Replace AppName with AppNameDUP push esi push edi invoke lstrlen,addr AppName mov ecx,eax LEA esi, AppNameDUP LEA edi, AppName push ds pop es cld rep movsb [edi],[esi] pop edi pop esi ; Add file info .IF ActiveFileFlag==1 invoke lstrcat,addr AppName,ofn.lpstrFile invoke SetWindowText,hWnd,AppName .ENDIF invoke SetFocus,hTextInput Ret ChangeDialogBoxTitle endp
问题分析与修复方案
核心问题拆解
- 标题恢复逻辑错误:你当前的复制/清空操作没有处理字符串终止符
\0,导致AppNameDUP可能包含垃圾数据;清空AppName时仅覆盖原标题长度的内容,拼接后变长的AppName会残留旧数据。 - 全局变量污染:
AppName作为全局变量被修改后,其他消息框如果直接引用它,自然会显示拼接后的内容。
具体修复步骤
1. 固定保存初始标题
程序初始化时(比如WM_CREATE消息处理中),就把对话框的初始标题保存到独立的全局变量OriginalAppName中,避免后续动态复制出错:
; 在WM_CREATE消息处理内执行 invoke GetWindowText, hWnd, addr OriginalAppName, MAX_PATH
2. 简化标题修改逻辑
直接基于初始标题进行拼接或恢复,无需复杂的复制清空操作:
ChangeDialogBoxTitle PROC hWnd .IF ActiveFileFlag == 1 ; 先恢复初始标题,再拼接文件名 invoke lstrcpy, addr AppName, addr OriginalAppName invoke lstrcat, addr AppName, ofn.lpstrFile invoke SetWindowText, hWnd, addr AppName .ELSE ; 关闭文件时直接恢复初始标题 invoke SetWindowText, hWnd, addr OriginalAppName invoke lstrcpy, addr AppName, addr OriginalAppName .ENDIF invoke SetFocus,hTextInput Ret ChangeDialogBoxTitle endp
3. 隔离消息框标题
所有消息框的标题直接使用OriginalAppName或者单独定义的常量字符串,彻底避免引用被修改后的AppName:
; 示例:消息框使用初始标题 invoke MessageBox, hWnd, addr MsgContent, addr OriginalAppName, MB_OK
4. 修复原有复制逻辑(可选)
如果坚持使用你原来的复制逻辑,必须手动添加字符串终止符,避免垃圾数据:
; 复制原标题到AppNameDUP后,补充终止符 push esi push edi invoke lstrlen, addr AppName mov ecx, eax LEA esi, AppName LEA edi, AppNameDUP push ds pop es cld rep movsb mov byte ptr [edi], 0 ; 添加字符串终止符 pop edi pop esi
内容的提问来源于stack exchange,提问作者Larry Alongi
相关产品推荐
相关产品推荐

