Tech

MFC의 기술적 역사와 2026년 현재: 유산인가 유물인가

1992년 Visual C++ 1.0과 함께 탄생한 MFC가 34년간 어떻게 진화했고, 왜 아직 살아있고, 언제 마이그레이션해야 하는지를 기술적 맥락에서 정리한다.

이런 분이 읽으면 좋습니다

요약: MFC(Microsoft Foundation Classes)는 1992년 탄생 이후 34년간 Windows 데스크톱 개발의 한 축을 담당해 왔다. 2026년 현재 Microsoft는 보안 업데이트만 제공하고 신규 기능은 없다. 하지만 금융 트레이딩 시스템, 산업 제어, 군수/방위 소프트웨어에서 MFC는 여전히 현역이다. 이 글은 MFC의 기술적 궤적을 정리하고, “지금 마이그레이션해야 하는가”라는 질문에 대한 판단 기준을 제시한다.

이 글은 MFC 기반 시스템을 유지보수하는 C++ 개발자, MFC 프로젝트의 미래를 결정해야 하는 기술 리드와 아키텍트, 그리고 레거시 시스템의 기술 부채를 평가해야 하는 엔지니어링 매니저를 대상으로 쓴다.


탄생과 전성기: 1992-2002

Win32 API의 고통에서 태어나다

1992년, Microsoft는 Visual C++ 1.0과 함께 MFC를 출시했다. 당시 Windows 개발은 순수 Win32 API로 이루어졌다. 윈도우 하나를 만들려면 RegisterClass, CreateWindow, GetMessage, DispatchMessage로 이어지는 수십 줄의 보일러플레이트가 필요했다. 메시지 루프를 직접 관리하고, WndProc 콜백에서 수백 개의 WM_ 메시지를 switch문으로 분기해야 했다.

MFC는 이 고통을 C++ 클래스 계층으로 감쌌다. CWnd, CDialog, CView, CDocument 같은 클래스가 Win32 API의 얇은 래퍼 역할을 했다. “얇은 래퍼”라는 점이 중요하다. MFC는 Win32 API를 추상화하거나 대체하는 것이 아니라, C++ 클래스로 포장만 했다. Win32 핸들(HWND, HDC)에 언제든 직접 접근할 수 있었고, 이것이 MFC의 가장 큰 강점이자 한계가 되었다.

Document/View 아키텍처

MFC의 핵심 설계 패턴은 Document/View 아키텍처였다. CDocument가 데이터를 보유하고, CView가 화면에 표시하며, CFrameWnd가 이 둘을 연결하는 구조다. 파일 열기/저장, 인쇄, 인쇄 미리보기 같은 표준 기능이 프레임워크 수준에서 제공되었다.

메시지 맵(Message Map)은 MFC의 또 다른 핵심이었다. Win32의 WndProc 콜백 대신, 매크로 기반의 선언적 메시지 라우팅을 제공했다. BEGIN_MESSAGE_MAPEND_MESSAGE_MAP 사이에 ON_COMMAND, ON_WM_PAINT 같은 매크로로 메시지 핸들러를 등록하는 방식이다. 가상 함수 대신 매크로를 선택한 것은 당시 C++ 컴파일러의 가상 함수 테이블 오버헤드를 피하기 위한 결정이었다.

전성기: Visual Studio 6.0 시대

1998년 출시된 Visual Studio 6.0은 MFC의 전성기였다. AppWizard로 프로젝트를 생성하면 SDI/MDI 애플리케이션의 뼈대가 즉시 만들어졌다. ClassWizard가 메시지 핸들러와 멤버 변수를 자동 생성해주었다. 리소스 에디터에서 다이얼로그를 시각적으로 디자인할 수 있었다.

이 시기 MFC로 만들어진 소프트웨어 목록은 인상적이다. AutoCAD, Adobe Photoshop의 일부 컴포넌트, 수많은 금융 트레이딩 터미널, 산업 자동화 HMI, 군수 시뮬레이션 소프트웨어가 MFC 기반이었다. Windows 데스크톱 앱을 만든다면 MFC가 사실상 표준이었다.


아키텍처의 강점과 구조적 한계

강점: Win32에 대한 직접 접근

MFC의 아키텍처적 강점은 명확하다:

  • Win32 API 완전 접근 — MFC 클래스를 쓰면서도 ::SendMessage, ::GetDC 같은 Win32 함수를 자유롭게 호출할 수 있다. 프레임워크가 가로막는 벽이 없다.
  • 예측 가능한 성능 — 얇은 래퍼이므로 오버헤드가 거의 없다. GC(Garbage Collection)가 없고, 메모리 할당과 해제를 개발자가 직접 제어한다.
  • 네이티브 바이너리 — 런타임 의존성 없이 .exe 하나로 배포 가능. .NET Framework나 JRE 설치를 요구하지 않는다.

한계: 시대가 지나간 설계 결정

동시에 MFC의 구조적 한계도 분명하다:

  • 매크로 기반 메시지 맵 — C++ 템플릿과 가상 함수가 충분히 빨라진 이후에도 매크로 방식을 유지했다. 디버깅이 어렵고, IDE 지원이 제한적이다.
  • 단일 스레드 가정 — MFC의 UI 클래스는 메인 스레드에서만 안전하게 동작한다. 멀티스레드 UI 업데이트는 PostMessageSendMessage를 통해 수동으로 처리해야 한다.
  • 수동 메모리 관리new/delete를 직접 관리해야 하며, 스마트 포인터 지원은 뒤늦게 추가되었다.
  • 데이터 바인딩 부재 — UI와 데이터의 자동 동기화 메커니즘이 없다. UpdateData(TRUE/FALSE) 매크로로 다이얼로그 변수를 수동 동기화하는 DDX/DDV가 전부다.

쇠퇴의 궤적: 2002-2020

.NET Framework의 등장 (2002)

2002년 .NET Framework 1.0과 Windows Forms가 등장하면서 MFC의 독점적 지위가 흔들리기 시작했다. C#은 C++보다 생산성이 높았고, Windows Forms는 MFC보다 배우기 쉬웠다. GC가 메모리 버그를 대폭 줄여주었고, 풍부한 BCL(Base Class Library)이 서드파티 라이브러리 의존도를 낮추었다.

그러나 이 시점에서 MFC가 갑자기 사라진 것은 아니다. 기존 MFC 코드베이스는 거대했고, C++ 개발자들이 C#으로 전환하는 데는 시간이 걸렸다.

WPF의 등장 (2006)

2006년 WPF(Windows Presentation Foundation)의 등장이 더 결정적이었다. XAML 기반 선언적 UI, 데이터 바인딩, 스타일/템플릿 시스템, 벡터 그래픽 렌더링 — MFC가 제공하지 못한 모든 현대적 UI 기능이 WPF에 있었다. MVVM 패턴을 통한 테스트 가능한 아키텍처는 MFC의 Document/View와 비교할 수 없었다.

웹 앱의 부상 (2010년대)

2010년대에 접어들면서 데스크톱 앱 자체의 영역이 줄어들었다. 기업 내부 도구가 웹 앱으로 전환되기 시작했고, SaaS 모델이 보편화되면서 “설치형 소프트웨어”의 시장이 축소되었다. MFC뿐 아니라 데스크톱 프레임워크 전체가 위축된 시기다.


2026년 현재: 보안 패치만 남은 프레임워크

Microsoft의 공식 입장

2026년 기준, MFC는 Visual Studio 2022 이후 버전에서 여전히 제공된다. C++ 데스크톱 개발 워크로드를 설치하면 MFC 라이브러리가 포함된다. Microsoft는 보안 취약점이 발견되면 패치를 배포한다.

그러나 신규 기능 추가는 2015년경 사실상 중단되었다. MFC Feature Pack(리본 UI, Visual Manager)이 마지막 의미 있는 업데이트였다. 공식 문서에서 MFC는 “유지보수 모드”라는 표현을 직접 쓰지 않지만, 행동이 그것을 말해준다. 새로운 Windows API나 컨트롤이 나와도 MFC 래퍼는 추가되지 않는다.

MFC가 아직 살아있는 곳

MFC가 여전히 현역으로 운용되는 영역은 다음과 같다:

  • 금융 트레이딩 시스템 — 마이크로초 단위의 지연 시간(latency)이 중요한 환경. 네이티브 C++ + Win32 직접 접근이 주는 성능 이점을 포기할 수 없다.
  • 산업 제어 시스템(SCADA/HMI) — 공장 자동화, 발전소 제어 등에서 수십 년간 안정적으로 동작해 온 MFC 기반 소프트웨어가 있다.
  • 군수/방위 소프트웨어 — 인증(certification) 요건이 핵심이다. DO-178C, MIL-STD 같은 규격으로 인증받은 소프트웨어를 프레임워크만 바꾸기 위해 재인증받는 것은 비현실적이다.
  • 엔터프라이즈 레거시 앱 — 수십만 줄 규모의 MFC 코드베이스를 보유한 기업이 아직 많다. 전면 재작성 비용이 유지보수 비용보다 큰 동안은 계속 운용된다.

마이그레이션 경로: 무엇으로, 언제

MFC (현행 유지)WPF (.NET 9)WinUI 3Qt 6웹 (Tauri/Electron)
언어 C++ (네이티브)C# (.NET)C# 또는 C++C++ (크로스플랫폼)JS/TS + Rust(Tauri)
플랫폼 Windows 전용Windows 전용Windows 10+Windows/Mac/LinuxWindows/Mac/Linux
성능 최상 (네이티브)우수 (JIT)우수 (WinAppSDK)우수 (네이티브)보통 (웹 렌더링)
기존 MFC 자산 활용 100%C++/CLI 인터롭COM 인터롭Win32 래핑 가능전면 재작성
UI 현대화 불가 (Win32 컨트롤)XAML + 데이터바인딩최신 Windows 디자인QML + 커스텀 스타일완전한 자유도
개발자 확보 매우 어려움비교적 수월성장 중수월 (글로벌)매우 수월
적합 시나리오 인증 필수, 변경 불가엔터프라이즈 LOB, 점진 전환Windows 전용 신규 앱크로스플랫폼 필수웹 전환 가능한 내부 도구
MFC에서 벗어나는 네 가지 경로. 만능 해법은 없으며, 코드베이스 규모와 플랫폼 요건에 따라 선택이 달라진다.

점진적 마이그레이션 vs 전면 재작성

WPF로의 점진적 전환이 가장 현실적인 경우가 많다. MFC 앱 내부에 WPF 컨트롤을 호스팅하거나(ElementHost), 반대로 WPF 앱에서 MFC 컨트롤을 임베딩하는(HwndHost) 기법으로 화면 단위 점진 전환이 가능하다. C++/CLI를 통해 기존 C++ 비즈니스 로직을 .NET에서 직접 호출할 수도 있다.

Qt로의 전환은 크로스플랫폼이 필수일 때 고려한다. C++ 언어를 유지할 수 있다는 점이 MFC 개발자에게 친숙하다. 다만 Qt의 시그널/슬롯 메커니즘과 MOC(Meta-Object Compiler) 빌드 시스템은 MFC와 상당히 다르므로 학습 비용이 있다.


마이그레이션 판단 기준: 유지 vs 전환

MFC를 유지해야 하는 경우:

  • 규제/인증 제약 — 소프트웨어가 특정 규격(DO-178C, IEC 62304 등)으로 인증되어 있고, 프레임워크 변경 시 재인증이 필요한 경우
  • 지연 시간 민감 — 마이크로초 단위의 성능이 비즈니스 요건이고, 관리형 언어의 GC 일시정지를 감수할 수 없는 경우
  • 코드베이스 규모 대비 변경 범위가 작은 경우 — 50만 줄짜리 MFC 앱에서 연간 변경이 5% 미만이라면, 전환 비용 대비 이득이 없다

MFC에서 벗어나야 하는 경우:

  • MFC 개발자 채용이 불가능해질 때 — 이것이 진짜 데드라인이다. C++/MFC를 아는 신규 개발자가 시장에서 사라지면, 유지보수 자체가 불가능해진다
  • Windows 이외 플랫폼 지원이 필요할 때 — MFC는 Windows 전용이다. Mac이나 Linux 지원이 요구되면 선택지가 없다
  • 현대적 UI/UX가 비즈니스 요건일 때 — MFC의 Win32 컨트롤로는 2026년 사용자가 기대하는 UI를 만들 수 없다
  • 기술 부채 유지 비용이 전환 비용을 초과할 때 — 버그 수정과 기능 추가에 드는 시간이 점점 늘어난다면, 어느 시점에서 전환이 경제적이 된다

결론: MFC는 유산이지 유물은 아니다

MFC는 나쁜 기술이 아니다. 1992년에 내린 설계 결정이 그 시대에는 합리적이었다. Win32 API를 직접 감싸는 얇은 래퍼라는 철학은 성능과 유연성을 동시에 제공했다. 문제는 그 설계 결정이 34년이 지난 지금도 유효한가다.

대부분의 경우 답은 “아니오”다. 데이터 바인딩 없는 UI, 매크로 기반의 메시지 라우팅, 수동 메모리 관리는 2026년 기준으로 생산성을 크게 떨어뜨린다. 그러나 “대부분”이 아닌 영역 — 규제 인증이 필수인 시스템, 마이크로초가 중요한 트레이딩 시스템, 전환 비용이 천문학적인 대규모 코드베이스 — 에서는 MFC가 여전히 합리적인 선택이다.

중요한 것은 감정이 아니라 판단이다. “오래되었으니까 바꿔야 한다”도, “잘 돌아가니까 그냥 두자”도 틀렸다. MFC 개발자를 더 이상 구할 수 없게 되는 시점이 마이그레이션의 실질적 마감일이며, 그 시점은 생각보다 가깝다.

다음에 읽을 글