#include <windows.h>
#include <vector>
#include <time.h>
using namespace std;
#ifdef UNICODE
#define String wstring
#else
#define String string
#endif // UNICODE
typedef struct
{
// Các thuộc tính mà Grid đề xuất cho Column và Cell sử dụng
HFONT Font = CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Courier New"));
//HFONT Font = CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Times New Roman"));
//HFONT Font = CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Sans serif"));
DWORD Align = DT_SINGLELINE | DT_VCENTER | DT_CENTER; // Align chung
int Margin = 10; // Margin chung
COLORREF BackColumn = GetSysColor(COLOR_3DLIGHT); // Màu nền chung cho các Columns
COLORREF ForeColumn = GetSysColor(COLOR_BTNTEXT); // Màu chữ chung cho các Columns
COLORREF NormalBackCell = RGB(0, 255, 255); // Màu nền chung cho các Cells
COLORREF NormalForeCell = RGB(255, 0, 0); // Màu chữ chung cho các Cells
COLORREF SelectBackCell = RGB(255, 0, 255); // Màu nền chung của các Cells chọn
COLORREF SelectForeCell = RGB(255, 255, 0); // Màu chữ chung của các Cells chọn
COLORREF SelectBackText = RGB(0, 0, 255); // Màu nền chung của text chọn
COLORREF SelectForeText = RGB(192, 192, 255); // Màu chữ chung của text chọn
COLORREF CaretColor = RGB(0, 0, 0); // Màu vẽ Caret chung
} SHAREPROP, *PSHAREPROP;
class CGlobal
{
public:
// Thay đổi màu một đối tượng
static bool ChangeColor(HWND hwnd, COLORREF & crColor)
{
CHOOSECOLOR cc;
COLORREF arColor[16];
ZeroMemory(&cc, sizeof(cc));
cc.lStructSize = sizeof(cc);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD)arColor;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
cc.rgbResult = crColor;
if (ChooseColor(&cc) && crColor != cc.rgbResult)
{
crColor = cc.rgbResult;
return true;
}
return false;
}
static int GetCellHeight(HDC hdc)
{
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
return tm.tmHeight + tm.tmExternalLeading + 4;
}
static int GetHeaderHeight(HDC hdc)
{
return GetCellHeight(hdc) + 2;
}
};
class CColumn
{
private:
bool m_selffont = false; // 1: Sử dụng font chữ riêng ?
bool m_selfalign = false; // 2: Sử dụng canh chỉnh riêng ?
bool m_selfmargin = false; // 3: Sử dụng khoảng chừa lề riêng ?
bool m_selfback = false; // 4: Sử dụng màu nền riêng ?
bool m_selffore = false; // 5: Sử dụng màu chữ riêng ?
HFONT m_font = NULL; // 6: Font riêng
DWORD m_align = 0; // 7: Align riêng
int m_margin = 0; // 8: Margin riêng
COLORREF m_back = 0; // 9: Màu nền riêng
COLORREF m_fore = 0; // 10: Màu chữ riêng
PSHAREPROP m_pshare = NULL; // 11: Con trỏ tới các thuộc tính dùng chung
String m_text = TEXT(""); // 12: Chuỗi text hiển thị
int m_width = 0; // 13: Chiều rộng column theo pixel
public:
// Khởi tạo - hủy
CColumn(PSHAREPROP pshare, String text, int width)
{
m_pshare = pshare;
m_text = text;
m_width = width;
}
~CColumn()
{
// Hủy font riêng nếu có
if (m_font)
DeleteObject(m_font);
}
// Thuộc tính
__declspec(property(get = _getSelfFont, put = _setSelfFont)) bool SelfFont; // 1
__declspec(property(get = _getSelfAlign, put = _setSelfAlign)) bool SelfAlign; // 2
__declspec(property(get = _getSelfMargin, put = _setSelfMargin)) bool SelfMargin; // 3
__declspec(property(get = _getSelfBack, put = _setSelfBack)) bool SelfBack; // 4
__declspec(property(get = _getSelfFore, put = _setSelfFore)) bool SelfFore; // 5
__declspec(property(get = _getFont, put = _setFont)) HFONT Font; // 6
__declspec(property(get = _getAlign, put = _setAlign)) DWORD Align; // 7
__declspec(property(get = _getMargin, put = _setMargin)) int Margin; // 8
__declspec(property(get = _getBack, put = _setBack)) COLORREF Back; // 9
__declspec(property(get = _getFore, put = _setFore)) COLORREF Fore; // 10
__declspec(property(get = _getSharePtr, put = _setSharePtr)) PSHAREPROP SharePtr; // 11
__declspec(property(get = _getText, put = _setText)) String Text; // 12
__declspec(property(get = _getWidth, put = _setWidth)) int Width; // 13
// Phương thức Get
bool _getSelfFont() { return m_selffont; } // 1
bool _getSelfAlign() { return m_selfalign;} // 2
bool _getSelfMargin() { return m_selfmargin; } // 3
bool _getSelfBack() { return m_selfback; } // 4
bool _getSelfFore() { return m_selffore; } // 5
HFONT _getFont() { return m_font; } // 6
DWORD _getAlign() { return m_align; } // 7
int _getMargin() { return m_margin; } // 8
COLORREF _getBack() { return m_back; } // 9
COLORREF _getFore() { return m_fore; } // 10
PSHAREPROP _getSharePtr() { return m_pshare; } // 11
String _getText() { return m_text; } // 12
int _getWidth() { return m_width; } // 13
// Phương thức Set
void _setSelfFont(bool self) { m_selffont = self; } // 1
void _setSelfAlign(bool self) { m_selfalign = self; } // 2
void _setSelfMargin(bool self) { m_selfmargin = self; } // 3
void _setSelfBack(bool self) { m_selfback = self; } // 4
void _setSelfFore(bool self) { m_selffore = self; } // 5
void _setFont(HFONT font) { m_font = font; } // 6
void _setAlign(DWORD align) { m_align = align; } // 7
void _setMargin(int margin) { m_margin = margin; } // 8
void _setBack(COLORREF color) { m_back = color; } // 9
void _setFore(COLORREF color) { m_fore = color; } // 10
void _setSharePtr(PSHAREPROP pshare) { m_pshare = pshare; } // 11
void _setText(String text) { m_text = text; } // 12
void _setWidth(int width) { m_width = width; } // 13
// Hàm công cộng
void Draw(HDC hdc, RECT rect)
{
// Vẽ khung như button
DrawFrameControl(hdc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
rect.left += 2;
rect.right -= 2;
rect.top += 2;
rect.bottom -= 2;
// Tô màu nền
HBRUSH hbr = CreateSolidBrush(m_selfback ? m_back : m_pshare->BackColumn);
FillRect(hdc, &rect, hbr);
DeleteObject(hbr);
// Tính khoảng canh lề
rect.left += (m_selfmargin ? m_margin : m_pshare->Margin) - 2;
rect.right -= (m_selfmargin ? m_margin : m_pshare->Margin) - 2;
// Vẽ text
SetTextColor(hdc, m_selffore ? m_fore : m_pshare->ForeColumn);
if (m_selffont)
SelectObject(hdc, m_font);
DrawText(hdc, m_text.c_str(), -1, &rect, m_selfalign ? m_align : m_pshare->Align);
if (m_selffont)
SelectObject(hdc, m_pshare->Font);
}
};
class CCell
{
private:
// Hàm cục bộ
public:
// Khởi tạo - hủy
// Thuộc tính
// Phương thức Get
// Phương thức Set
// Hàm công cộng
};
class CItem
{
private:
// Hàm cục bộ
public:
// Khởi tạo - hủy
// Thuộc tính
// Phương thức Get
// Phương thức Set
// Hàm công cộng
};
class CGrid
{
private:
SHAREPROP m_shareprop; // Các thuộc tính dùng chung
HWND m_hwnd = NULL; // Thẻ cửa sổ
COLORREF m_back = RGB(64, 128, 128); // Màu nền
bool m_noheader = false; // Điều khiển có Header hay không ?
vector<CColumn*> m_columns; // Các ColumnHeader
vector<CItem*> m_items; // Các Items dòng
// Thủ tục xử lý sự kiện
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == WM_CREATE)
{
LPCREATESTRUCT pcs = reinterpret_cast<LPCREATESTRUCT>(lparam);
CGrid * pGrid = reinterpret_cast<CGrid*>(pcs->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, PtrToUlong(pGrid));
return pGrid->OnCreate(hwnd);
}
CGrid * pGrid = reinterpret_cast<CGrid*>(static_cast<LONG_PTR>(GetWindowLongPtr(hwnd, GWLP_USERDATA)));
switch (msg)
{
case WM_SIZE: return pGrid->OnSize(lparam);
case WM_SETFOCUS: return pGrid->OnSetFocus();
case WM_KILLFOCUS: return pGrid->OnKillFocus();
case WM_ERASEBKGND: return pGrid->OnEraseBackGround();
case WM_PAINT: return pGrid->OnPaint();
case WM_LBUTTONDOWN: return pGrid->OnLButtonDown(lparam);
case WM_MOUSEMOVE: return pGrid->OnMouseMove(lparam);
case WM_LBUTTONUP: return pGrid->OnLButtonUp(lparam);
case WM_CONTEXTMENU: return pGrid->OnContextMenu(wparam, lparam);
case WM_COMMAND: return pGrid->OnCommand(wparam, lparam);
case WM_KEYDOWN: return pGrid->OnKeyDown(wparam, lparam);
case WM_CHAR: return pGrid->OnChar(wparam);
case WM_VSCROLL: return pGrid->OnVScroll(wparam);
case WM_HSCROLL: return pGrid->OnHScroll(wparam);
case WM_MOUSEWHEEL: return pGrid->OnMouseWheel(wparam);
case WM_TIMER: return pGrid->OnTimer(wparam);
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
// Các bộ xử lý sự kiện
LRESULT OnCreate(HWND hwnd)
{
m_hwnd = hwnd;
// Chưa hiển thị các thanh cuộn
SetScrollRange(hwnd, SB_VERT, 0, 0, FALSE);
SetScrollRange(hwnd, SB_HORZ, 0, 0, FALSE);
return 0;
}
LRESULT OnSize(LPARAM lparam)
{
Refresh();
return 0;
}
LRESULT OnKillFocus()
{
Refresh();
return 0;
}
LRESULT OnSetFocus()
{
Refresh();
return 0;
}
LRESULT OnEraseBackGround()
{
return -1;
}
LRESULT OnPaint()
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, &ps);
EndPaint(m_hwnd, &ps);
Refresh();
return 0;
}
LRESULT OnLButtonDown(LPARAM lparam)
{
SetFocus(m_hwnd);
return 0;
}
LRESULT OnMouseMove(LPARAM lparam)
{
return 0;
}
LRESULT OnLButtonUp(LPARAM lparam)
{
return 0;
}
LRESULT OnCommand(WPARAM wparam, LPARAM lparam)
{
return DefWindowProc(m_hwnd, WM_COMMAND, wparam, lparam);
}
LRESULT OnContextMenu(WPARAM wparam, LPARAM lparam)
{
return DefWindowProc(m_hwnd, WM_CONTEXTMENU, wparam, lparam);
}
LRESULT OnKeyDown(WPARAM wparam, LPARAM lparam)
{
return DefWindowProc(m_hwnd, WM_KEYDOWN, wparam, lparam);
}
LRESULT OnChar(WPARAM wparam)
{
return 0;
}
LRESULT OnVScroll(WPARAM wparam)
{
return 0;
}
LRESULT OnHScroll(WPARAM wparam)
{
return 0;
}
LRESULT OnMouseWheel(WPARAM wparam)
{
return 0;
}
LRESULT OnTimer(WPARAM wparam)
{
return 0;
}
// Các hàm vẽ lên DC bộ nhớ
void FillBack(HDC hdc, RECT rect)
{
// Tô nền DC
HBRUSH hbr = CreateSolidBrush(m_back);
FillRect(hdc, &rect, hbr);
DeleteObject(hbr);
}
void DrawHeader(HDC hdc, RECT rect)
{
rect.bottom = rect.top + CGlobal::GetHeaderHeight(hdc);
if (m_columns.empty())
FillRect(hdc, &rect, GetSysColorBrush(COLOR_3DFACE));
else
{
rect.right += 2; // Vẽ tràn ra ngoài để mất biên phải - thẩm mỹ
DrawFrameControl(hdc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
rect.right -= 2;
DrawColumns(hdc, rect);
}
}
void DrawColumns(HDC hdc, RECT rect)
{
int xStart = 0;
int numcolumns = m_columns.size();
for (int i = 0; i < numcolumns; xStart += m_columns[i++]->Width)
{
rect.left = xStart;
rect.right = rect.left + m_columns[i]->Width;
m_columns[i]->Draw(hdc, rect);
}
}
void DrawItems(HDC hdc, RECT rect)
{
}
public:
// Khởi tạo - hủy
CGrid()
{
m_columns.resize(0);
m_items.resize(0);
}
~CGrid()
{
for (int i = m_columns.size() - 1; i >= 0; i--)
delete m_columns[i];
for (int i = m_items.size() - 1; i >= 0; i--)
delete m_items[i];
DeleteObject(m_shareprop.Font);
}
// Thuộc tính
__declspec(property(get = _getColumns)) vector<CColumn*> & Columns;
// Phương thức Get
vector<CColumn*> & _getColumns() { return m_columns; }
// Phương thức Set
// Các hàm công cộng
HWND Create(HINSTANCE instance, HWND parent, int left, int top, int width, int height)
{
// Sử dụng biến tĩnh để tránh đăng ký nhiều lần
static bool registered = false;
WNDCLASS w;
w.lpszClassName = TEXT("GridviewClass32");
if (!registered)
{
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hbrBackground = NULL;
w.hCursor = LoadCursor(NULL, IDC_ARROW);
w.hIcon = NULL;
w.hInstance = instance;
w.lpfnWndProc = WndProc;
w.lpszMenuName = NULL;
w.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&w))
return NULL;
registered = true;
}
return CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME, w.lpszClassName, NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | WS_CLIPCHILDREN,
left, top, width, height, parent, NULL, instance, this);
}
void Move(int left, int top, int width, int height, BOOL redraw)
{
MoveWindow(m_hwnd, left, top, width, height, redraw);
}
void Refresh()
{
// Hàm dùng kỹ thuật vẽ trên DC bộ nhớ để chống nháy hình, chỉ vẽ chồng 1 lần duy nhất
RECT r;
GetClientRect(m_hwnd, &r);
int cx = r.right - r.left;
int cy = r.bottom - r.top;
HDC hdc = GetDC(m_hwnd);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
// Bắt đầu vẽ trên DC bộ nhớ
SelectObject(hdcMem, hBitmap);
SelectObject(hdcMem, m_shareprop.Font);
SetBkMode(hdcMem, TRANSPARENT);
FillBack(hdcMem, r); // Tô nền DC Memory
if (!m_noheader)
DrawHeader(hdcMem, r); // Vẽ Header
if (!m_items.empty())
{
if (!m_noheader)
r.top += CGlobal::GetHeaderHeight(hdcMem);
DrawItems(hdcMem, r); // Vẽ các Items
}
// Vẽ từ DC bộ nhớ lên DC màn hình chỉ 1 lần duy nhất
BitBlt(hdc, 0, 0, cx, cy, hdcMem, 0, 0, SRCCOPY);
// Giải phóng các đối tượng
DeleteObject(hBitmap);
DeleteDC(hdcMem);
ReleaseDC(m_hwnd, hdc);
}
// Cộng thêm 1 column vào cuối Header
void AddColumn(const PTCHAR columntext, int columnwidth)
{
m_columns.push_back(new CColumn(&m_shareprop,columntext, columnwidth));
Refresh();
}
// Cộng thêm nhiều columns 1 lần
void AddColumns(const PTCHAR * pcolumntext, int * pcolumnwidth, int count)
{
for (int i = 0; i < count; i++)
m_columns.push_back(new CColumn(&m_shareprop, pcolumntext[i], pcolumnwidth[i]));
Refresh();
}
// Chèn thêm 1 column tại chỉ mục
void InsertColumn(int index, const PTCHAR columntext, int columnwidth)
{
if (index < 0)
return;
if (index < (int)m_columns.size())
m_columns.insert(m_columns.begin() + index, new CColumn(&m_shareprop, columntext, columnwidth));
else
m_columns.push_back(new CColumn(&m_shareprop, columntext, columnwidth));
Refresh();
}
// Chèn thêm nhiều column từ chỉ mục
void InsertColumns(int index, const PTCHAR * pcolumntext, int * pcolumnwidth, int count)
{
if (index < 0)
return;
if (index < (int)m_columns.size())
{
for (int i = 0; i < count; i++)
m_columns.insert(m_columns.begin() + index, new CColumn(&m_shareprop, pcolumntext[i], pcolumnwidth[i]));
}
else
{
for (int i = 0; i < count; i++)
m_columns.push_back(new CColumn(&m_shareprop, pcolumntext[i], pcolumnwidth[i]));
}
Refresh();
}
// Xóa column tại chỉ mục
void DeleteColumn(int index)
{
if (0 <= index && index < (int)m_columns.size())
m_columns.erase(m_columns.begin() + index);
Refresh();
}
// Xóa tất cả column
void DeleteAllColumns()
{
for (int i = m_columns.size() - 1; i >= 0; i--)
m_columns.erase(m_columns.begin() + i);
Refresh();
}
};
class CWindow
{
enum
{
// Định danh MenuItem
IDM_FILE_NEW = 10001, IDM_FILE_OPEN, IDM_FILE_SAVE, IDM_FILE_CLOSE, IDM_FILE_EXIT,
IDM_OPTION_BACKGROUND,
};
private:
HWND m_hwnd = NULL; // Thẻ cửa sổ
COLORREF m_crBack = RGB(128, 128, 128); // Màu nền
CGrid m_grid; // Một thể hiện lớp Grid
// Thủ tục xử lý sự kiện
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == WM_CREATE)
{
LPCREATESTRUCT pcs = reinterpret_cast<LPCREATESTRUCT>(lparam);
CWindow * pWindow = reinterpret_cast<CWindow*>(pcs->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, PtrToUlong(pWindow));
return pWindow->OnCreate(pcs->hInstance, hwnd);
}
CWindow * pWindow = reinterpret_cast<CWindow*>(static_cast<LONG_PTR>(GetWindowLongPtr(hwnd, GWLP_USERDATA)));
switch (msg)
{
case WM_SIZE: return pWindow->OnSize(lparam);
case WM_COMMAND: return pWindow->OnCommand(wparam, lparam);
case WM_CLOSE: return pWindow->OnClose(wparam, lparam);
case WM_DESTROY: return pWindow->OnDestroy();
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
// Các bộ xử lý sự kiện
LRESULT OnCreate(HINSTANCE instance, HWND hwnd)
{
m_hwnd = hwnd;
m_grid.Create(instance, hwnd, 0, 0, 0, 0);
srand((UINT)time(NULL));
return 0;
}
LRESULT OnSize(LPARAM lparam)
{
// Cho Grid chiếm gần hết cửa sổ Test
m_grid.Move(20, 20, LOWORD(lparam) - 40, HIWORD(lparam) - 40, TRUE);
return 0;
}
LRESULT OnCommand(WPARAM wparam, LPARAM lparam)
{
switch (LOWORD(wparam))
{
case IDM_FILE_NEW: MenuClick_New(); return 0;
case IDM_FILE_OPEN: MenuClick_Open(); return 0;
case IDM_FILE_SAVE: MenuClick_Save(); return 0;
case IDM_FILE_CLOSE: MenuClick_Close(); return 0;
case IDM_FILE_EXIT: MenuClick_Exit(); return 0;
case IDM_OPTION_BACKGROUND: MenuClick_BackGround(); return 0;
}
return DefWindowProc(m_hwnd, WM_COMMAND, wparam, lparam);
}
LRESULT OnClose(WPARAM wparam, LPARAM lparam)
{
DestroyWindow(m_hwnd);
return 0;
}
LRESULT OnDestroy()
{
PostQuitMessage(0);
return 0;
}
// Các hàm xử lý trình đơn
void MenuClick_New()
{
if (!m_grid.Columns.empty())
m_grid.DeleteAllColumns();
TCHAR szText[MAX_PATH];
int cRand = rand() % 7 + 4; // khoảng [4,10]
for (int c = 0; c < cRand; c++)
{
wsprintf(szText, TEXT("Column %d"), c + 1);
m_grid.AddColumn(szText, rand() % 151 + 100); // khoảng [100,250]
}
EnableMenuItem(GetMenu(m_hwnd), IDM_FILE_CLOSE, MF_ENABLED);
}
void MenuClick_Open()
{
}
void MenuClick_Save()
{
}
void MenuClick_Close()
{
}
void MenuClick_Exit()
{
SendMessage(m_hwnd, WM_CLOSE, 0, 0);
}
void MenuClick_BackGround()
{
if (CGlobal::ChangeColor(m_hwnd, m_crBack))
{
DeleteObject((HBRUSH)SetClassLongPtr(m_hwnd, GCLP_HBRBACKGROUND, (long)CreateSolidBrush(m_crBack)));
InvalidateRect(m_hwnd, NULL, TRUE);
}
}
HMENU BuildMenu()
{
HMENU hMenu = CreateMenu();
HMENU hFile = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hFile, TEXT("&File"));
AppendMenu(hFile, MF_STRING, IDM_FILE_NEW, TEXT("&New"));
AppendMenu(hFile, MF_STRING, IDM_FILE_OPEN, TEXT("&Open..."));
AppendMenu(hFile, MF_STRING | MF_GRAYED, IDM_FILE_SAVE, TEXT("&Save..."));
AppendMenu(hFile, MF_STRING | MF_GRAYED, IDM_FILE_CLOSE, TEXT("&Close"));
AppendMenu(hFile, MF_SEPARATOR, 0, NULL);
AppendMenu(hFile, MF_STRING, IDM_FILE_EXIT, TEXT("&Exit"));
HMENU hOption = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hOption, TEXT("&Option"));
AppendMenu(hOption, MF_STRING, IDM_OPTION_BACKGROUND, TEXT("&BackGround..."));
return hMenu;
}
public:
int Create(HINSTANCE hInst)
{
// Đăng ký lớp
WNDCLASS w;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hbrBackground = CreateSolidBrush(m_crBack);
w.hCursor = LoadCursor(NULL, IDC_ARROW);
w.hIcon = LoadIcon(NULL, IDI_APPLICATION);
w.hInstance = hInst;
w.lpfnWndProc = WndProc;
w.lpszClassName = TEXT("TestGridview");
w.lpszMenuName = NULL;
w.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&w))
return 0;
// Tạo cửa sổ
HWND hwnd = CreateWindow(w.lpszClassName, w.lpszClassName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, BuildMenu(), hInst, this);
if (!hwnd)
return 0;
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
// Vòng lặp thông điệp
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
};
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
CWindow Window;
return Window.Create(hInst);
}