MFC merangkum banyak kontrol yang umum digunakan dan merangkum nama kelas tanpa menyediakan antarmuka yang jelas. Untuk menulis program jendela menggunakan win api, langkah pertama adalah mendaftarkan kelas jendela.
Saat ini, nama kelas dan nama judul didaftarkan bersama, sehingga judul dapat dengan mudah diatur oleh pengguna. Nama kelas juga harus sangat sederhana. Sayangnya, MFC tidak melakukan ini bisa diubah terus menerus, tapi nama kelasnya tidak bisa. Nama kelas jendela ditentukan oleh Buat. Sebelum Buat, Anda harus memilih nama kelas jendela yang terdaftar untuk jendela tersebut. Sebagai parameter, jendela Buat akan baik-baik saja. Pembuatan CWnd pada akhirnya akan menuju ke CreateEx di CreateEx. Jauh lebih jelas
BOOL CWND :: CreateSEX (DWORD DWEXSTYLE, LPCTSTR LPSZClassName, LPCTSTR LPSZWINDOWName, DWORD DWSTYLE, Const Rect & Rect, Cwnd* pParentwnd, uint nid, lpvoid lpparam /* = nol* /) , rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), (HMENU)(UINT_PTR)nID, lpParam);}BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam){ ASSERT(lpszClassName == NULL || AfxIsValidString(lpszClassName) || Afx IsV alidAtom( lpszClassName )); ENSURE_ARG(lpszWindowName == NULL || AfxIsValidString(lpszWindowName)); // izinkan modifikasi beberapa parameter pembuatan umum CREATESTRUCT cs; gaya = dwStyle; cs.x = x; cs.y = y; cs.cx = nLebar; cs.cy = nTinggi; ) { PostNcDestroy(); return FALSE; } AfxHookWindowCreate(ini); cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);#ifdef _DEBUG if (hWnd == NULL) { TRACE(traceAppMsg, 0, "Peringatan : Pembuatan jendela gagal: GetLastError mengembalikan 0x%8.8 Xn", GetLastError()); }#endif if (!AfxUnhookWindowCreate()) PostNcDestroy(); // pembersihan jika CreateWindowEx gagal terlalu cepat jika (hWnd == NULL) return FALSE; ASSERT(hWnd == m_hWnd); // seharusnya diset pada send msg hook return TRUE;}
Anda dapat melihat bahwa akhirnya mencapai::AfxCtxCreateWindowEx. Anda dapat dengan mudah mengetahui bahwa CreateWindowEx dipanggil di sini untuk membuat jendela.
Ada PreCreateWindow(cs) di depan, dan setelah cs diproses oleh PreCreateWindow, diserahkan ke ::AfxCtxCreateWindowEx untuk diproses
::AfxCtxCreateWindowEx ditransfer ke CreateWindowEx. cs.lpszClass adalah nama kelasnya, yang memperjelas bahwa AfxCtxCreateWindowEx memiliki niat baik.
Kita dapat membebani PreCreateWindow untuk mengubah nama kelas, sebagai berikut:
// TODO: Tambahkan kode khusus di sini dan/atau panggil kelas dasar //VERIFY(AfxDeferRegisterClass(AFX_WND_REG)); //AfxEndDeferRegisterClass(AFX_WND_REG); //cs.lpszClass = AfxRegisterWndClass(NULL); 0, sizeof(WNDCLASS)); // mulai dengan NULL // default wndcls.style = CS_DBLCLKS |. CS_HREDRAW |. //Anda dapat menentukan prosedur jendela Anda sendiri wndcls.lpfnWndProc = ::DefWindowProc; ; wndcls.hIcon = NULL; // atau muat ikon lain wndcls.hCursor =NULL; wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wndcls.lpszClassName = _T("MyNewClass"); // Daftarkan kelas baru dan keluar jika gagal if(!AfxRegisterClass(&wndcls)) { TRACE("Pendaftaran Kelas Gagaln"); return FALSE; wndcls.lpszClassName; kembalikan BENAR; //kembalikan CWnd::PreCreateWindow(cs);
Faktanya, ini untuk meneruskan string nama kelas terdaftar ke CreateWindowEx. Dilihat dari komentar pada kode di atas, saya juga menggunakan AfxRegisterWndClass, sebuah metode yang memungkinkan sistem menghasilkan className. CWnd::PreCreateWindow tidak sesuai dengan keinginan saya, jadi saya berkomentar. Sebenarnya tidak ada apa-apa di dalamnya, itu hanya penilaian. Di MFC, kelas turunan CWnd lainnya tidak sesederhana itu. Namun, cukup memodifikasi nama kelas dan membebani metode ini secara berlebihan akan baik-baik saja.
Ya, kebanyakan bisa. Sayangnya cara ini tidak bisa dilakukan untuk Dialog, karena tidak menggunakan CWnd::Create, sehingga tidak bisa dielakkan.
PreCreateWindow akan muncul. Anda dapat membebani metode kotak dialog ini secara berlebihan. Karena pembuatan CDialog bisa langsung menggunakan API sistem, dan tidak perlu repot CWnd untuk mentransfer ke CReateWindowEx, sehingga tidak bisa menggunakan cara di atas untuk mengubah nama kelas kotak dialog.
Lihatlah kode pembuatannya:
BOOL CDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd){ ASSERT(IS_INTRESOURCE(lpszTemplateName) || AfxIsValidString(lpszTemplateName)); m_lpszTemplateName = lpszTemplateName; // digunakan untuk bantuan jika (IS_INTRESOURCE(m_lpszTemplateName) && m_nID Bantuan == 0) m_nIDHelp = LOWORD((DWORD_PTR)m_lpszTemplateName);#ifdef _DEBUG if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE)) { ASSERT(FALSE); // nama template dialog tidak valid PostNcDestroy(); } #endif //_DEBUG HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG); HRSRC hResource = ::FindResource(hInst, lpszTemplateName, HGLOBAL hTemplate = LoadResource(hInst, hResource); BOOL bResult = CreateIndirect(hTemplate, pParentWnd, hInst ) ; Sumber Daya Gratis(hTemplate); mengembalikan bHasil;}
Dapat dilihat bahwa CDialog dibuat oleh sumber daya. Hal ini dapat dilakukan dengan cara ini. Tentukan Kelas "nama kelas dialog" di skrip sumber daya. Daftarkan nama kelas ini sebelum domodal atau Buat di kotak dialog, lalu tunggu modal dan Buat. Itu saja.
Selama kurun waktu ini, saya disibukkan dengan aspek lain, dan saya banyak lupa tentang mekanisme pengemasan MFC. Saya akan menelusuri kodenya sebagai penyegaran.