如何用 HANDLE 或 HINSTANCE 得到 HWND

rucio 2009-08-27 11:12:26
我程序的目的很简单,通过函数运行一个外部应用程序,然后通过SendMessage把它正常关了(不会因为关进程发生其他不必要问题)

ShellExecuteEx 可以得到 HANDLE 和 HINSTANCE 但是 SendMessage需要 HWND才行。
现在不知道如何用 HANDLE 或 HINSTANCE 得到 HWND

下面这段是原因,可以不看。
--------------------------------------------------------------------------------------------------------------------
之所以用 ShellExecuteEx不用CreateProcess,是因为 CreateProcess 的参数位置有 引号不认
例如CreateProcess(NULL, "chrome.exe --user-data-dir=\"D:\\Program Files\\data\"", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
这里的 \" CreateProcess 就认不了。
一囧之下,发现 ShellExecuteEx 可以认 \"
但是 ShellExecuteEx就可以认得到 \"
--------------------------------------------------------------------------------------------------------------------
...全文
886 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoshang_program 2009-09-03
  • 打赏
  • 举报
回复
3楼正确 GetWindowLong
MoXiaoRab 2009-09-03
  • 打赏
  • 举报
回复

ULONG pid = 0;
NTSTATUS status = 0;
NTSTATUS rc = 0;
PEPROCESS EProcess;
LPTSTR lpCurProc;

//调用ZwQueryInformationProcess得到PID
ULONG Rlen;
PVOID pBuffer;
PROCESS_BASIC_INFORMATION *pbi;
pBuffer = ExAllocatePoolWithTag(PagedPool, sizeof(PROCESS_BASIC_INFORMATION),0x123456);
status = ZwQueryInformationProcess(ProcessHandle,
ProcessBasicInformation,
pBuffer,
sizeof(PROCESS_BASIC_INFORMATION),
&Rlen);
if(!NT_SUCCESS(status))
{
ExFreePool(pBuffer);//释放分配的内存
//DbgPrint("ZwQueryInformationProcess() wrong!\n");
//return -1;
rc = (NTSTATUS)(REALZwTerminateProcess)RealZwTerminateProcess(ProcessHandle,ExitStatus);
return rc;
}
pbi = (struct _PROCESS_BASIC_INFORMATION *)pBuffer;
//DbgPrint("ProcessHandle代表进程%d!",pbi->UniqueProcessId);
pid = (ULONG)pbi->UniqueProcessId;

以上代码可以移植到Ring3下使用,从Ntdll.dll导出函数

然后你遍历所有的窗口,可以用GetWindow或是EnumWindow都随便你,GetWindowThreadProcessId得到这个窗口的PID,和上面得到的PID进行比较就行了
MoXiaoRab 2009-09-03
  • 打赏
  • 举报
回复
#5的看反要求了
rucio 2009-08-28
  • 打赏
  • 举报
回复
用 EnumWindows ,又如何和 HANDLE 或 HINSTANCE比较,判断是我想要的窗口呢?
fengrx 2009-08-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 rucio 的回复:]
用 EnumWindows ,又如何和 HANDLE 或 HINSTANCE比较,判断是我想要的窗口呢?
[/Quote]

LONG GetWindowLong(
HWND hWnd, // handle to window
int nIndex // offset of value to retrieve
);
第二个参数设置为GWL_HINSTANCE,第一个参数为窗口句柄,可以得到HINSTANCE。
jyh_baoding 2009-08-28
  • 打赏
  • 举报
回复
想法得到窗口句柄
wltg2001 2009-08-27
  • 打赏
  • 举报
回复
现在不知道如何用 HANDLE 或 HINSTANCE 得到 HWND
=============
应该是没有办法的,因为HANDLE是进程的句柄,而HWND是窗口句柄,一个进程并不一定只有一个窗口,有的进程没有窗口,有的进程可能有多个窗口.要想获取HWND,最方便是FindWindow()
雪影 2009-08-27
  • 打赏
  • 举报
回复
一个HINSTANCE实例中可能存在多个窗口。
可以通过窗口找到所处的进程,而不能通过进程得到窗口HWND,因为可能有多个窗口啊。

窗口查找使用FindWindow或EnumWindows
对日常债务进行数据库操作 .586 .model flat,stdcall option casemap:none include pay.inc include p_Func.asm include p_const.asm include p_struct.asm include p_data.asm include macro.mac .data hInstance HINSTANCE ? CommandLine LPSTR ? hParent dword ? hCursor dword ? hconn_g dword ? henv_g dword ? hstmt_g dword ? dwCount_g dword ? bFlag_g dword ? pPayForData_g PAYFORDATA <> pConfigData CONFIGDATA <> .code include p_code.asm include p_db.asm include p_Dialog.asm include p_ListView.asm include P_ini.asm include p_html.asm ; --------------------------------------------------------------------------- start: invoke GetModuleHandle, NULL mov hInstance,eax invoke DialogBoxParam,hInstance,addr LoginDlgName,0,addr LoginDialog,NULL .if bFlag_g invoke GetCommandLine mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT .endif invoke ExitProcess,eax WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND LOCAL hMenu:HWND LOCAL hAccelerator:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,offset MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_MAIN_ICON mov wc.hIcon,eax mov wc.hIconSm,eax mov hMainIco,eax invoke LoadMenu,hInstance,IDR_MENU mov hMenu,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke LoadCursor,hInstance,IDI_HANDLE_ICON mov hCursor,eax invoke LoadAccelerators,hInstance,IDA_ACCELERATOR mov hAccelerator,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,hMenu,\ hInst,NULL mov hwnd,eax mov hParent,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL invoke UpdateWindow, hwnd .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateAccelerator,hwnd,hAccelerator,addr msg .if eax == 0 invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .endif .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc uses ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local @stFont:LOGFONT,@hFont:DWORD LOCAL @dwColor:dword .IF uMsg==WM_DESTROY invoke KillTimer,hWnd,IDC_TIMER_STATUSBAR invoke PostQuitMessage,NULL .elseif uMsg==WM_TIMER .if wParam==IDC_TIMER_STATUSBAR invoke _PrintMsg_3 .endif .ELSEIF uMsg==WM_CREATE invoke SetTimer,hWnd,IDC_TIMER_STATUSBAR ,1000,NULL invoke LoadIcon,hInstance,IDI_MAIN_ICON invoke SendMessage, hWnd, WM_SETICON, ICON_BIG,eax ;control invoke _DoToolBar,hInstance,hWnd,IDC_MAIN_TB mov hToolBar,eax ;invoke _DoEdit,hInstance,hToolBar,IDC_MAIN_EDIT ;mov hEdit,eax ;invoke _DoButton,hInstance,hToolBar,IDC_MAIN_BUTTON,_T("搜索") ;mov hButton,eax ;LABEL invoke _DoLabel,hInstance,hToolBar,IDC_BTN_LABEL_3,200,3,150,20 invoke SetDlgItemText,hToolBar,IDC_BTN_LABEL_3,_T("当前用户:") invoke _DoLabel,hInstance,hToolBar,IDC_BTN_LABEL_NAME,270,3,150,20 invoke _DoLabel,hInstance,hToolBar,IDC_BTN_LABEL_1,340,3,150,20 invoke SetDlgItemText,hToolBar,IDC_BTN_LABEL_1,_T("借入:") invoke _DoLabel,hInstance,hToolBar,IDC_BTN_LABEL_IN,380,3,150,20 invoke _DoLabel,hInstance,hToolBar,IDC_BTN_LABEL_2,480,3,150,20 invoke SetDlgItemText,hToolBar,IDC_BTN_LABEL_2,_T("借出:") invoke _DoLabel,hInstance,hToolBar,IDC_BTN_LABEL_OUT,520,3,150,20 invoke _DoStatusBar,hInstance,hWnd,IDC_MAIN_SB mov hStatusBar,eax invoke _DoListView,hInstance,hWnd,IDC_MAIN_LSV mov hListView ,eax invoke _InsertColumnToMainListV,hListView invoke _DoPopupMainMenu, hInstance,hWnd mov hPopupMainMenu,eax invoke _InitConfig,hWnd .elseif uMsg==WM_NOTIFY push edi mov edi, lParam mov eax, [edi.NMHDR].hwndFrom .if eax==hListView .if [edi.NMHDR].code==NM_DBLCLK ;双击 .elseif [edi.NMHDR].code==NM_CLICK ;单击 invoke _GetCurrentFocus,hListView,addr pPayForData_g .elseif [edi.NMHDR].code==NM_RCLICK ;右击 invoke _GetCurrentFocus,hListView,addr pPayForData_g invoke _ShowPopupMainMenu,hWnd,hPopupMainMenu .endif .endif pop edi .elseif uMsg==WM_COMMAND .if lParam !=0 ;工具栏 LOWORD wParam .if eax==IDC_TBB_NEW invoke DialogBoxParam,hInstance,addr NewDlgName,hWnd,addr IddNewDialog,NULL .elseif eax==IDC_TBB_SEE invoke DialogBoxParam,hInstance,addr SeeDlgName,hWnd,addr SeeDialog,NULL .elseif eax==IDC_TBB_PRINT invoke _Print_Html,hWnd .elseif eax==IDC_TBB_HELP invoke DialogBoxParam,hInstance,addr AboutDlgName,hWnd,addr AboutDialog,NULL .elseif eax==IDC_TBB_EXIT invoke SendMessage,hWnd,WM_CLOSE,0,0 .endif .elseif lParam ==0 HIWORD wParam .if eax==0 ;菜单栏 mov eax,wParam .if ax==IDM_NEW invoke DialogBoxParam,hInstance,addr NewDlgName,hWnd,addr IddNewDialog,NULL invoke _RefreshMTData,hWnd,hListView .elseif ax==IDM_SEE invoke DialogBoxParam,hInstance,addr SeeDlgName,hWnd,addr SeeDialog,NULL .elseif ax==IDM_PRINT invoke _Print_Html,hWnd .elseif ax==IDM_CALC invoke _OpenProgramExeFile,hWnd,addr SZCALC,NULL .elseif ax==IDM_HELP invoke DialogBoxParam,hInstance,addr AboutDlgName,hWnd,addr AboutDialog,NULL .elseif ax==IDM_PWD invoke DialogBoxParam,hInstance,addr PwdDlgName,hWnd,addr PwdDialog,NULL .elseif ax==IDM_REFRESH invoke _RefreshMTData,hWnd,hListView .elseif ax==IDM_DEMO invoke DialogBoxParam,hInstance,addr DemoDlgName,hWnd,addr DemoDialog,NULL .elseif ax==IDM_CAL invoke _PromptMsg,_T("建设中...") .endif .elseif eax==1 ;快捷键 .endif .endif .elseif uMsg ==WM_SIZE .if wParam!=SIZE_MINIMIZED invoke SendMessage,hStatusBar,uMsg,wParam,lParam invoke SendMessage,hToolBar,uMsg,wParam,lParam mov eax,lParam mov edx,eax and eax,0ffffh shr edx,16 sub edx,46 invoke MoveWindow,hListView, 0, 28, eax,edx,TRUE mov eax,lParam and eax,0ffffh mov ebx,eax sub eax,210 sub ebx,55 invoke MoveWindow,hEdit, eax, 3,150,20,TRUE invoke MoveWindow,hButton,ebx, 3,50,20,TRUE .endif .elseif uMsg==WM_SIZING LimitWindowWidth 455 LimitWindowHeight 455 .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp _RefreshMTData proc hWnd:dword,hOwner:dword pushad ;连接数据库 invoke DBConnect,hWnd .if eax invoke _PrintMsg_1,_T("数据库连接成功!") .endif ;显示数据 invoke SQLExecDirect,hstmt_g,addr SHOW_ALL_RECODE_MT,sizeof SHOW_ALL_RECODE_MT .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO ;73570000h invoke _ReadMTToMainListV,hOwner,hstmt_g mov dwCount_g,eax invoke _PrintMsg_2,dwCount_g,_T(" ") invoke _PrintMsg_1,_T("加载成功!") .endif invoke DisDBConnect,hWnd .if eax invoke _PrintMsg_1,_T("断开与数据库的连接!") .endif popad ret _RefreshMTData endp _RefreshOPData proc hWnd:dword,hOwner:dword LOCAL @nCount:dword pushad ;连接数据库 invoke DBConnect,hWnd .if eax invoke _PrintMsg_1,_T("数据库连接成功!") .endif ;显示数据 invoke SQLExecDirect,hstmt_g,addr SHOW_ALL_RECODE_OP,sizeof SHOW_ALL_RECODE_OP .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO ;73570000h invoke _ReadOPToSeeListV,hOwner,hstmt_g mov @nCount,eax invoke _SetGroupText,hWnd,@nCount invoke _PrintMsg_1,_T("加载成功!") .endif invoke DisDBConnect,hWnd .if eax invoke _PrintMsg_1,_T("断开与数据库的连接!") .endif popad ret _RefreshOPData endp _InitConfig proc hWnd:dword LOCAL @Buff[MAX_PATH]:byte pushad invoke _RefreshMTData,hWnd,hListView invoke SetDlgItemText,hToolBar,IDC_BTN_LABEL_NAME,addr pConfigData.szName invoke _CalcMTPayForRecord,hWnd,addr pConfigData.szName,FALSE mov dwMoneyIn,eax invoke wsprintf,addr @Buff,addr szMoney,dwMoneyIn invoke SetDlgItemText,hToolBar,IDC_BTN_LABEL_IN,addr @Buff invoke _CalcMTPayForRecord,hWnd,addr pConfigData.szName,TRUE mov dwMoneyOut,eax invoke wsprintf,addr @Buff,addr szMoney,dwMoneyOut invoke SetDlgItemText,hToolBar,IDC_BTN_LABEL_OUT,addr @Buff ;TITLE invoke RtlZeroMemory,addr @Buff,sizeof @Buff invoke lstrcpy,addr @Buff,addr pConfigData.szAppName invoke lstrcat,addr @Buff,_T(" -- ") invoke lstrcat,addr @Buff,addr pConfigData.szName invoke SendMessage,hWnd,WM_SETTEXT,0,addr @Buff popad ret _InitConfig endp end start
vc++深入了解源代码 (1) #include #include LRESULT CALLBACK WinSunProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state ) { WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); wndcls.hIcon=LoadIcon(NULL,IDI_ERROR); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WinSunProc; wndcls.lpszClassName="sunxin2006"; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&wndcls); HWND hwnd; hwnd=CreateWindow("sunxin2006","http://www.sunxin.org",WS_OVERLAPPEDWINDOW, 0,0,600,400,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WinSunProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_CHAR: char szChar[20]; sprintf(szChar,"char code is %d",wParam); MessageBox(hwnd,szChar,"char",0); break; case WM_LBUTTONDOWN: MessageBox(hwnd,"mouse clicked","message",0); HDC hdc; hdc=GetDC(hwnd); TextOut(hdc,0,50,"程序员之家",strlen("程序员之家")); //ReleaseDC(hwnd,hdc); break; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC=BeginPaint(hwnd,&ps); TextOut(hDC,0,0,"http://www.sunxin.org",strlen("http://www.sunxin.org")); EndPaint(hwnd,&ps); break; case WM_CLOSE: if(IDYES==MessageBox(hwnd,"是否真的结束?","message",MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; }
#include #include LRESULT CALLBACK WinSunProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window ) { WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); wndcls.hIcon=LoadIcon(NULL,IDI_ERROR); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WinSunProc; wndcls.lpszClassName="weixin2003"; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&wndcls); HWND hwnd; hwnd=CreateWindow("weixin2003","±±¾©Î¬Ð¿Æѧ¼¼ÊõÅàѵÖÐÐÄ",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WinSunProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_CHAR: char szChar[20]; sprintf(szChar,"char is %d",wParam); MessageBox(hwnd,szChar,"weixin",0); break; case WM_LBUTTONDOWN: MessageBox(hwnd,"mouse clicked","weixin",0); HDC hdc; hdc=GetDC(hwnd); TextOut(hdc,0,50,"¼ÆËã»ú±à³ÌÓïÑÔÅàѵ",strlen("¼ÆËã»ú±à³ÌÓïÑÔÅàѵ")); ReleaseDC(hwnd,hdc); break; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC=BeginPaint(hwnd,&ps); TextOut(hDC,0,0,"άÐÂÅàѵ",strlen("άÐÂÅàѵ")); EndPaint(hwnd,&ps); break; case WM_CLOSE: if(IDYES==MessageBox(hwnd,"ÊÇ·ñÕæµÄ½áÊø£¿","weixin",MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; }
编写一个如示例WinMain的Windows应用程序,其中窗口的背景色、光标、图标等属性可以设置成自己喜欢的风格。作为该示例的扩展,要求编程实现当在该窗口中单击右键时,播放一曲自己喜欢的音乐。(4学时) 编写一个如示例ExDlgCtl的MFC对话框应用程序,其中必须实现的功能包括: “对话框”菜单下的模态对话框、非模态对话框和文件对话框; “控件”菜单下的计算器、动态创建按钮、上网问卷调查、调整对话框背景色等四个对话框。 示例中的其它功能可以根据实际情况决定是否编写。(4学时) 3)编写一个如示例ExMenu的MFC菜单、工具栏和状态栏的应用程序,编写该实验时注意功能的完整性,包括两个菜单的切换、右键弹出式菜单、工具栏的切换、状态栏信息格的添加等功能。(4学时) 4)编写一个如示例ExDraw的MFC绘图应用程序,实现画点、线、矩形、椭圆等图形,并可以根据用户选择的画笔和画刷进行绘制,最后要求实现画笔的功能。(4学时) LRESULT CALLBACK WinProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window ) { WNDCLASS wndclas; wndclas.cbClsExtra=0; wndclas.cbWndExtra=0; wndclas.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndclas.hCursor=LoadCursor(NULL,IDC_ARROW); wndclas.hIcon=LoadIcon(NULL,IDI_EXCLAMATION); wndclas.hInstance=hInstance; wndclas.lpfnWndProc=WinProc; wndclas.lpszClassName="ABCD"; wndclas.lpszMenuName=NULL; wndclas.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&wndclas;); void CTestView::OnDialogModal() //模态对话框 { // TODO: Add your command handler code here CTestDlg1 dlg; dlg.DoModal(); } void CTestView::OnDialogModalless()//非模态对话框 { // TODO: Add your command handler code here CTestDlg2 *pd=new CTestDlg2(); pd->Create(IDD_DIALOG2,this); pd->ShowWindow(SW_SHOW); } void CTestView::OnDialogFile() //文件对话框 {

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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