如何做一个象Windows2000 Open file dialog那样的对话框?期待高手指教!

chenkan2000 2001-11-30 12:52:46
...全文
127 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
prog_st 2001-12-03
  • 打赏
  • 举报
回复
Email,给例程。
codemon 2001-12-03
  • 打赏
  • 举报
回复
呵呵,好像不能。不如自己做一个,也不难哦。
chenkan2000 2001-12-01
  • 打赏
  • 举报
回复
大家可能误会我的意思了。我要的不是File Dialog,而是象Windows 2000 File Dialog那样的对话框。左边是一个button list,右边放属性页,点击一个button,右边换一个属性页。不知道能不能利用Win2000 File Dialog。
codemon 2001-11-30
  • 打赏
  • 举报
回复
>>>
用法和CFileDialog一样。
其实就是CFileDialog的源码,做了一点小改动。呵呵。
codemon 2001-11-30
  • 打赏
  • 举报
回复
>>>FileDlgEx.cpp


#include "filedlgex.h"

#ifdef AFX_AUX_SEG
#pragma code_seg(AFX_AUX_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif


CFileDlgEx::CFileDlgEx(LPCTSTR lpszFileName,CWnd* pParentWnd) : CCommonDialog(pParentWnd)
{
if(!lpszFileName || !lpszFileName[0])
{
throw;
return;
}
memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
m_ofn.lStructSize = sizeof(m_ofn);

m_szFileName[0] = '\0';
m_szFileTitle[0] = '\0';
m_pofnTemp = NULL;

m_bOpenFileDialog = TRUE;
m_nIDHelp = AFX_IDD_FILEOPEN;

m_ofn.lpstrFile = m_szFileName;
m_ofn.nMaxFile = _countof(m_szFileName);
m_ofn.lpstrDefExt = NULL;
m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
m_ofn.nMaxFileTitle = _countof(m_szFileTitle);
m_ofn.lStructSize = sizeof(m_ofn);
m_ofn.Flags = OFN_HIDEREADONLY | OFN_ENABLESIZING |OFN_SHOWHELP | OFN_EXPLORER;
m_ofn.hInstance = AfxGetResourceHandle();
m_ofn.lpfnHook=NULL;
// setup initial file name

// Translate filter into commdlg format (lots of \0)
if (lpszFileName != NULL)
{
m_strFilter = lpszFileName;
m_strFilter += "|";
m_strFilter += lpszFileName;
m_strFilter += "||";
LPTSTR pch = m_strFilter.GetBuffer(0); // modify the buffer in place
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
m_ofn.lpstrFilter = m_strFilter;
// do not call ReleaseBuffer() since the string contains '\0' characters
}
}

CFileDlgEx::CFileDlgEx(BOOL bOpenFileDialog,
LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags,
LPCTSTR lpszFilter, CWnd* pParentWnd) : CCommonDialog(pParentWnd)
{
memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
m_ofn.lStructSize = sizeof(m_ofn);

m_szFileName[0] = '\0';
m_szFileTitle[0] = '\0';
m_pofnTemp = NULL;

m_bOpenFileDialog = bOpenFileDialog;
m_nIDHelp = bOpenFileDialog ? AFX_IDD_FILEOPEN : AFX_IDD_FILESAVE;

m_ofn.lpstrFile = m_szFileName;
m_ofn.nMaxFile = _countof(m_szFileName);
m_ofn.lpstrDefExt = lpszDefExt;
m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
m_ofn.nMaxFileTitle = _countof(m_szFileTitle);
m_ofn.lStructSize = sizeof(m_ofn);
m_ofn.Flags |= dwFlags | OFN_ENABLESIZING |OFN_SHOWHELP;
#if (_WIN32_WINNT < 0x0400)
m_ofn.Flags |= OFN_EXPLORER;
#endif
#if (_WIN32_WINNT < 0x0500)
m_ofn.Flags |=OFN_ENABLEHOOK;
#endif
m_ofn.hInstance = AfxGetResourceHandle();
m_ofn.lpfnHook=NULL;
// setup initial file name
if (lpszFileName != NULL)
lstrcpyn(m_szFileName, lpszFileName, _countof(m_szFileName));

// Translate filter into commdlg format (lots of \0)
if (lpszFilter != NULL)
{
m_strFilter = lpszFilter;
LPTSTR pch = m_strFilter.GetBuffer(0); // modify the buffer in place
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
m_ofn.lpstrFilter = m_strFilter;
// do not call ReleaseBuffer() since the string contains '\0' characters
}
}

int CFileDlgEx::DoModal()
{
ASSERT_VALID(this);

// zero out the file buffer for consistent parsing later
ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile));
DWORD nOffset = lstrlen(m_ofn.lpstrFile)+1;
ASSERT(nOffset <= m_ofn.nMaxFile);
memset(m_ofn.lpstrFile+nOffset, 0, (m_ofn.nMaxFile-nOffset)*sizeof(TCHAR));

HWND hWndFocus = ::GetFocus();
BOOL bEnableParent = FALSE;
m_ofn.hwndOwner = PreModal();


int nResult;
if (m_bOpenFileDialog)
nResult = ::GetOpenFileName(&m_ofn);
else
nResult = ::GetSaveFileName(&m_ofn);

// WINBUG: Second part of special case for file open/save dialog.
if (bEnableParent)
::EnableWindow(m_ofn.hwndOwner, TRUE);
if (::IsWindow(hWndFocus))
::SetFocus(hWndFocus);

PostModal();
return nResult ? nResult : IDCANCEL;
}

CString CFileDlgEx::GetPathName() const
{
if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
{
ASSERT(::IsWindow(m_hWnd));
CString strResult;
if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
{
strResult.Empty();
}
else
{
strResult.ReleaseBuffer();
}

if (!strResult.IsEmpty())
{
if (GetParent()->SendMessage(CDM_GETFILEPATH, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
strResult.Empty();
else
{
strResult.ReleaseBuffer();
return strResult;
}
}
}
return m_ofn.lpstrFile;
}

CString CFileDlgEx::GetFileName() const
{
if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
{
ASSERT(::IsWindow(m_hWnd));
CString strResult;
if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
{
strResult.Empty();
}
else
{
strResult.ReleaseBuffer();
return strResult;
}
}
return m_ofn.lpstrFileTitle;
}

CString CFileDlgEx::GetFileExt() const
{
if ((m_ofn.Flags & OFN_EXPLORER) && m_hWnd != NULL)
{
ASSERT(::IsWindow(m_hWnd));
CString strResult;
if (GetParent()->SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
(LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
strResult.Empty();
else
{
strResult.ReleaseBuffer();
int pos = strResult.ReverseFind('.');
if (pos >= 0)
return strResult.Right(strResult.GetLength() - pos - 1);
strResult.Empty();
}
return strResult;
}

if (m_pofnTemp != NULL)
if (m_pofnTemp->nFileExtension == 0)
return &afxChNil;
else
return m_pofnTemp->lpstrFile + m_pofnTemp->nFileExtension;

if (m_ofn.nFileExtension == 0)
return &afxChNil;
else
return m_ofn.lpstrFile + m_ofn.nFileExtension;
}

CString CFileDlgEx::GetFileTitle() const
{
CString strResult = GetFileName();
int pos = strResult.ReverseFind('.');
if (pos >= 0)
return strResult.Left(pos);
return strResult;
}

CString CFileDlgEx::GetNextPathName(POSITION& pos) const
{
BOOL bExplorer = m_ofn.Flags & OFN_EXPLORER;
TCHAR chDelimiter;
if (bExplorer)
chDelimiter = '\0';
else
chDelimiter = ' ';

LPTSTR lpsz = (LPTSTR)pos;
if (lpsz == m_ofn.lpstrFile) // first time
{
if ((m_ofn.Flags & OFN_ALLOWMULTISELECT) == 0)
{
pos = NULL;
return m_ofn.lpstrFile;
}

// find char pos after first Delimiter
while(*lpsz != chDelimiter && *lpsz != '\0')
lpsz = _tcsinc(lpsz);
lpsz = _tcsinc(lpsz);

// if single selection then return only selection
if (*lpsz == 0)
{
pos = NULL;
return m_ofn.lpstrFile;
}
}

CString strPath = m_ofn.lpstrFile;
if (!bExplorer)
{
LPTSTR lpszPath = m_ofn.lpstrFile;
while(*lpszPath != chDelimiter)
lpszPath = _tcsinc(lpszPath);
strPath = strPath.Left(lpszPath - m_ofn.lpstrFile);
}

LPTSTR lpszFileName = lpsz;
CString strFileName = lpsz;

// find char pos at next Delimiter
while(*lpsz != chDelimiter && *lpsz != '\0')
lpsz = _tcsinc(lpsz);

if (!bExplorer && *lpsz == '\0')
pos = NULL;
else
{
if (!bExplorer)
strFileName = strFileName.Left(lpsz - lpszFileName);

lpsz = _tcsinc(lpsz);
if (*lpsz == '\0') // if double terminated then done
pos = NULL;
else
pos = (POSITION)lpsz;
}

// only add '\\' if it is needed
if (!strPath.IsEmpty())
{
// check for last back-slash or forward slash (handles DBCS)
LPCTSTR lpsz = _tcsrchr(strPath, '\\');
if (lpsz == NULL)
lpsz = _tcsrchr(strPath, '/');
// if it is also the last character, then we don't need an extra
if (lpsz != NULL &&
(lpsz - (LPCTSTR)strPath) == strPath.GetLength()-1)
{
ASSERT(*lpsz == '\\' || *lpsz == '/');
return strPath + strFileName;
}
}
return strPath + '\\' + strFileName;
}

CString CFileDlgEx::GetFolderPath() const
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);

CString strResult;
if (GetParent()->SendMessage(CDM_GETFOLDERPATH, (WPARAM)MAX_PATH, (LPARAM)strResult.GetBuffer(MAX_PATH)) < 0)
strResult.Empty();
else
strResult.ReleaseBuffer();
return strResult;
}

void CFileDlgEx::SetControlText(int nID, LPCSTR lpsz)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
GetParent()->SendMessage(CDM_SETCONTROLTEXT, (WPARAM)nID, (LPARAM)lpsz);
}

void CFileDlgEx::HideControl(int nID)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
GetParent()->SendMessage(CDM_HIDECONTROL, (WPARAM)nID, 0);
}

void CFileDlgEx::SetDefExt(LPCSTR lpsz)
{
ASSERT(::IsWindow(m_hWnd));
ASSERT(m_ofn.Flags & OFN_EXPLORER);
GetParent()->SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpsz);
}

UINT CFileDlgEx::OnShareViolation(LPCTSTR)
{
ASSERT_VALID(this);

// Do not call Default() if you override
return OFN_SHAREWARN; // default
}

BOOL CFileDlgEx::OnFileNameOK()
{
ASSERT_VALID(this);

// Do not call Default() if you override
return FALSE;
}

void CFileDlgEx::OnLBSelChangedNotify(UINT, UINT, UINT)
{
ASSERT_VALID(this);

// Do not call Default() if you override
// no default processing needed
}

void CFileDlgEx::OnInitDone()
{
ASSERT_VALID(this);
GetParent()->CenterWindow();

// Do not call Default() if you override
// no default processing needed
}

void CFileDlgEx::OnFileNameChange()
{
ASSERT_VALID(this);

// Do not call Default() if you override
// no default processing needed
}

void CFileDlgEx::OnFolderChange()
{
ASSERT_VALID(this);

// Do not call Default() if you override
// no default processing needed
}

void CFileDlgEx::OnTypeChange()
{
ASSERT_VALID(this);

// Do not call Default() if you override
// no default processing needed
}

BOOL CFileDlgEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
ASSERT(pResult != NULL);

// allow message map to override
if (CCommonDialog::OnNotify(wParam, lParam, pResult))
return TRUE;

OFNOTIFY* pNotify = (OFNOTIFY*)lParam;
switch(pNotify->hdr.code)
{
case CDN_INITDONE:
OnInitDone();
return TRUE;
case CDN_SELCHANGE:
OnFileNameChange();
return TRUE;
case CDN_FOLDERCHANGE:
OnFolderChange();
return TRUE;
case CDN_SHAREVIOLATION:
*pResult = OnShareViolation(pNotify->pszFile);
return TRUE;
case CDN_HELP:
if (!SendMessage(WM_COMMAND, ID_HELP))
SendMessage(WM_COMMANDHELP, 0, 0);
return TRUE;
case CDN_FILEOK:
*pResult = OnFileNameOK();
return TRUE;
case CDN_TYPECHANGE:
OnTypeChange();
return TRUE;
}

return FALSE; // not handled
}

////////////////////////////////////////////////////////////////////////////
// CFileDialog diagnostics

#ifdef _DEBUG
void CFileDlgEx::Dump(CDumpContext& dc) const
{
CDialog::Dump(dc);

if (m_bOpenFileDialog)
dc << "File open dialog";
else
dc << "File save dialog";
dc << "\nm_ofn.hwndOwner = " << (UINT)m_ofn.hwndOwner;
dc << "\nm_ofn.nFilterIndex = " << m_ofn.nFilterIndex;
dc << "\nm_ofn.lpstrFile = " << m_ofn.lpstrFile;
dc << "\nm_ofn.nMaxFile = " << m_ofn.nMaxFile;
dc << "\nm_ofn.lpstrFileTitle = " << m_ofn.lpstrFileTitle;
dc << "\nm_ofn.nMaxFileTitle = " << m_ofn.nMaxFileTitle;
dc << "\nm_ofn.lpstrTitle = " << m_ofn.lpstrTitle;
dc << "\nm_ofn.Flags = " << (LPVOID)m_ofn.Flags;
dc << "\nm_ofn.lpstrDefExt = " << m_ofn.lpstrDefExt;
dc << "\nm_ofn.nFileOffset = " << m_ofn.nFileOffset;
dc << "\nm_ofn.nFileExtension = " << m_ofn.nFileExtension;

dc << "\nm_ofn.lpstrFilter = ";
LPCTSTR lpstrItem = m_ofn.lpstrFilter;
LPTSTR lpszBreak = _T("|");

while (lpstrItem != NULL && *lpstrItem != '\0')
{
dc << lpstrItem << lpszBreak;
lpstrItem += lstrlen(lpstrItem) + 1;
}
if (lpstrItem != NULL)
dc << lpszBreak;

dc << "\nm_ofn.lpstrCustomFilter = ";
lpstrItem = m_ofn.lpstrCustomFilter;
while (lpstrItem != NULL && *lpstrItem != '\0')
{
dc << lpstrItem << lpszBreak;
lpstrItem += lstrlen(lpstrItem) + 1;
}
if (lpstrItem != NULL)
dc << lpszBreak;

dc << "\n";
}

#endif //_DEBUG

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

IMPLEMENT_DYNAMIC(CFileDlgEx, CDialog)

codemon 2001-11-30
  • 打赏
  • 举报
回复
>>>


#ifndef ___FILE_DLG_EX_H_INCLUDE__
#define ___FILE_DLG_EX_H_INCLUDE__

#define _WIN32_WINNT 0x0500//windows2000
//#define _WIN32_WINNT 0x0400//Win98

#include <afxwin.h>
#include <afxcmn.h>
#include <afxdlgs.h>
#include <afxpriv.h>
#include <shlobj.h>

#ifndef _countof
#define _countof(array) (sizeof(array)/sizeof(array[0]))
#endif

class CFileDlgEx : public CCommonDialog
{
DECLARE_DYNAMIC(CFileDlgEx)

public:
// Attributes
OPENFILENAME m_ofn; // open file parameter block

// Constructors
CFileDlgEx(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL);

CFileDlgEx(LPCTSTR lpszFileName,CWnd* pParentWnd = NULL);

// Operations
virtual int DoModal();

// Helpers for parsing file name after successful return
// or during Overridable callbacks if OFN_EXPLORER is set
CString GetPathName() const; // return full path and filename
CString GetFileName() const; // return only filename
CString GetFileExt() const; // return only ext
CString GetFileTitle() const; // return file title
BOOL GetReadOnlyPref() const; // return TRUE if readonly checked

// Enumerating multiple file selections
POSITION GetStartPosition() const;
CString GetNextPathName(POSITION& pos) const;

// Other operations available while the dialog is visible
CString GetFolderPath() const; // return full path
void SetControlText(int nID, LPCSTR lpsz);
void HideControl(int nID);
void SetDefExt(LPCSTR lpsz);

// Overridable callbacks
protected:
virtual UINT OnShareViolation(LPCTSTR lpszPathName);
virtual BOOL OnFileNameOK();
virtual void OnLBSelChangedNotify(UINT nIDBox, UINT iCurSel, UINT nCode);

// only called back if OFN_EXPLORER is set
virtual void OnInitDone();
virtual void OnFileNameChange();
virtual void OnFolderChange();
virtual void OnTypeChange();

// Implementation
#ifdef _DEBUG
public:
virtual void Dump(CDumpContext& dc) const;
#endif

protected:
BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save
CString m_strFilter; // filter string
// separate fields with '|', terminate with '||\0'
TCHAR m_szFileTitle[64]; // contains file title after return
TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return

OPENFILENAME* m_pofnTemp;
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
};

#endif
georgehuang 2001-11-30
  • 打赏
  • 举报
回复
自己去查MSDN上关于CFileDlg类的信息,你会找到你要的答案的
codemon 2001-11-30
  • 打赏
  • 举报
回复
给你一个CFileDlgEx类,在2000下编译显示Windows2000下的file dialog,在98下编译显示Windows98下的file dialog

>>>>>

【前言】 工作或学习中可能需要实现基于VC读\写Excel文件的功能,本人最近也遇到了该问题。中间虽经波折,但是最终还是找到了解决问题的办法。 在此跟大家分享,希望对跟我同样迷茫过的同学们有所帮助。 1、程序功能 1)打开一个excel文件; 2)显示到CListCtrl上; 3)新建一个Excel文件。 以上均在对话框中实现。 2、平台 VC++2010 3、实现方法 常用的Excel打开方式有两种 1)通过数据库打开; 2)OLE方式打开。 由于方式1)操作繁琐,经常出现莫名的错误,这里选用方式2). 4、准备步骤 首先新建一个Dialog窗体程序,添加list control和两个按钮 1)将ExcelLib文件夹拷贝到程序目录下; 2)将Export2Excel.h,Export2Excel.cpp两个文件添加到项目; 3)包含头文件,#include "ExcelLib/Export2Excel.h" 通过以上步骤在程序中引入了可以读取Excle文件的CExport2Excel类; 5、打开excel文件 通过按钮点击打开 void CExcelTestDlg::OnBnClickedButtonOpenExcel() { //获取文件路径 CFileDialog* lpszOpenFile; CString szGetName; lpszOpenFile = new CFileDialog(TRUE,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"Excel File(*.xlsx;*.xls)|*.xls;*.xlsx",NULL); if (lpszOpenFile->DoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //打开文件 //文件中包含多个sheet时,默认打开第一个sheet CExport2Excel Excel_example; Excel_example.OpenExcel(szGetName); //获取sheet个数 int iSheetNum = Excel_example.GetSheetsNumber(); //获取已使用表格行列数 int iRows = Excel_example.GetRowCount(); int iCols = Excel_example.GetColCount(); //获取单元格的内容 CString cs_temp = Excel_example.GetText(1,1); //AfxMessageBox(cs_temp); //List control上显示 //获取工作表列名(第一行) CStringArray m_HeadName; m_HeadName.Add(_T("ID")); for (int i=1;iGetItemCount()>0) { m_list.DeleteColumn(0); } //初始化ClistCtrl,加入列名 InitList(m_list,m_HeadName); //填入内容 //第一行是标题,所以从第2行开始 CString num; int pos; for (int row = 2;row<=iRows; row++) { pos = m_list.GetItemCount(); num.Format(_T("%d"),pos +1); m_list.InsertItem(pos,num); for (int colum=1;columDoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //文件全名称 CString csFileName = szGetName; //需要添加的两个sheet的名称 CString csSheetName = "newSheet"; CString csSheetName2 = "newSheet2"; // 新建一个excel文件,自己写入文字 CExport2Excel Excel_example; //新建excel文件 Excel_example.CreateExcel(csFileName); //添加sheet,新加的sheet在前,也就是序号为1 Excel_example.CreateSheet(csSheetName); Excel_example.CreateSheet(csSheetName2); //操作最开始添加的sheet:(newSheet) Excel_example.SetSheet(2); //添加表头 Excel_example.WriteHeader(1,"第一列"); Excel_example.WriteHeader(2,"第二列"); //添加核心数据 Excel_example.WriteData(1,1,"数据1"); Excel_example.WriteData(1,2,"数据2"); //保存文件 Excel_example.Save(); //关闭文件 Excel_example.Close(); } 7、注意事项 1)一般单个Excel文件包含多个sheet,程序默认打开第一个; 2)指定操作sheet,使用Excel_example.SetSheet(2)函数; 3)打开文件时最左侧的sheet序号为1,新建excel时最新添加的sheet序号为1. 【后记】 本程序主要基于网络CSDN中---“Excel封装库V2.0”---完成,下载地址是:http://download.csdn.net/detail/yeah2000/3576494,在此表示感谢!同时, 1)在其基础上作了小改动,改正了几个小错误,添加了几个小接口; 2)添加了如何使用的例子,原程序是没有的; 3)详细的注释 发现不足之处,还请大家多多指教

16,551

社区成员

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

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

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