Related
I saw an article on the Microsoft website MSDN that introduced an advanced way of writing.
I apply it to the extension of the class, and usually I don't have a problem.
But recently I encountered a problem when I tried to write a class.
I want to implement a listview class to provide us some convenience when we manipulate the listview control.
template <class DERIVED_TYPE>
class BaseWindow
{
public:
LPCTSTR className = "myWindows";
LPCTSTR Caption = "myWindows";
DWORD Style = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
UINT classStyle = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
DWORD ExStyle = 0;
...
other_property
...
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DERIVED_TYPE *pThis = NULL;
if (uMsg == WM_NCCREATE)
{
CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
if (pThis)pThis->m_hwnd = hwnd;
}else{
pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(pThis)pThis->m_hwnd = hwnd;
}
if (pThis)
{
return pThis->HandleMessage(hwnd, uMsg, wParam, lParam);
}else{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
ATOM RegClass()
{
WNDCLASS wc = { 0 };
wc.lpfnWndProc = BaseWindow::WindowProc;
wc.hInstance = hInst;
wc.lpszClassName = className;
wc.style = classStyle;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
return RegisterClass(&wc);
}
BOOL CreateWinEx( LPCTSTR className_,LPCTSTR Caption_,
DWORD Style_,DWORD ExStyle_,
int x_,int y_,int w_,int h_,
HWND hWndParent_,HMENU hMenu_,HINSTANCE hInst_)
{
m_hwnd = CreateWindowEx(
ExStyle_, className_, Caption_, Style_,
x_, y_, w_, h_,
hWndParent_, hMenu_, hInst_, this
);
return (m_hwnd ? TRUE : FALSE);
}
BOOL Create()
{
ATOM rst = RegClass();
if(rst == 0) return FALSE;
m_hwnd = CreateWindowEx(
ExStyle, className, Caption, Style,
x, y, w, h,
hWndParent, hMenu, hInst, this
);
return (m_hwnd ? TRUE : FALSE);
}
}
Based on the above, I have derived two classes, one as the main form and the other as the listview class that I am going to design.
class FirstWindow : public BaseWindow<FirstWindow>
{
public:
FirstWindow(){};
...
some_property
...
LRESULT HandleMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
};
class listView : public BaseWindow<listView>
{
public:
listView();
int init(LPCTSTR className_,HWND hWndParent_,int x,int y,int w,int h)
{
this->className = className_;
this->hWndParent = hWndParent_;
this->Style = WS_CHILD| WS_VISIBLE | ~WS_CAPTION;
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->Create();
hWndMsgWindow = m_hwnd;
CreateListView(hWndMsgWindow);
ShowWindow(hWndMsgWindow,SW_SHOW);
ShowWindow(hWndListView,SW_SHOW);
UpdateWindow(hWndMsgWindow);
UpdateWindow(hWndListView);
idebug("listview::init >> hWndMsgWindow:%d,parent:%d, error:%d\n",hWndMsgWindow,GetParent(hWndMsgWindow), GetLastError());
idebug("listview::init >> hWndListView:%d,parent:%d,error:%d\n",hWndListView,GetParent(hWndListView), GetLastError());
return 1;
}
LRESULT HandleMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT listView::CreateListView(HWND hwndParent_)
{
InitCommonControls();
bool rst = CreateWinEx(WC_LISTVIEW, NULL,
WS_CHILD | WS_VISIBLE | LVS_REPORT |LVS_EDITLABELS | LVS_NOCOLUMNHEADER | LVS_OWNERDATA |LVS_OWNERDRAWFIXED | WS_BORDER,0,
x,y,w,h,
hwndParent_, NULL, GetModuleHandle(NULL));
if(rst)
hWndListView = m_hwnd;
idebug("CreateListView >> rst:%d,hwndlistview:%d,parent:%d,hwndParent_:%d, error:%d\n",rst,hWndListView,GetParent(hWndListView),hwndParent_, GetLastError());
return rst;
}
LRESULT AddItem();
LRESULT OnListViewNotify(HWND hwnd, LPARAM lParam);
void OwnerDraw(LPDRAWITEMSTRUCT lpdis, HDC hdc, HWND hWnd, const TCHAR* szDraw);
void on_drawItem(HWND hWnd, LPARAM lParwm);
void on_notify(HWND hWnd, WPARAM wParwm, LPARAM lParam);
void on_create(HWND hWnd);
void on_measureItem(LPARAM lParam);
bool add_item();
bool add_item_sub();
...
some_property
...
};
fire FirstWindow first
FirstWindow * pFirstWnd;
listView lv;
int main(int argc, char** argv)
{
FirstWindow win;
pFirstWnd = &win;
win.className = "FirstWindow";
win.Style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
win.x = 100;
win.y = 100;
win.w = 600;
win.h = 300;
bool rst = win.Create();
if (!rst)
{
idebug("getlasterror:%d,line:201\n", GetLastError());
bug.ShowErr();
}
else {
lv.init("mylistview",pFirstWnd->m_hwnd,20,20,300,200);
ShowWindow(lv.m_hwnd, SW_SHOW);
}
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
The goal of the listview_class is to be able to receive and process window messages independently. not like this:
LRESULT FirstWindow::HandleMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
//lv.init("mylistview2",pFirstWnd->m_hwnd,20,20,300,200);
//ShowWindow(lv.m_hwnd, SW_SHOW);
break;
}
case WM_NOTIFY:
{
lv.on_notify(hWnd,wParam,lParam);
break;
}
...
}
default:
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
return TRUE;
}
Instead, I want to process messages independently within listview class,like this:
LRESULT listView::HandleMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
static HDC hdc;
HRESULT lResult;
switch (uMsg)
{
case WM_CREATE:
{
idebug("class_listview >> WM_CREATE >> hWnd :%d, className:%s, parent:%d\n",hWnd, className , GetParent(hWnd));
//HWND h = CreateWindowEx(0, WC_LISTVIEW, NULL,
WS_CHILD | WS_VISIBLE | LVS_REPORT |LVS_EDITLABELS | LVS_NOCOLUMNHEADER | LVS_OWNERDATA |LVS_OWNERDRAWFIXED | WS_BORDER,
20,20,300,200,
hWnd,NULL, GetModuleHandle(NULL),NULL);
//ShowWindow(h,SW_SHOW);
//UpdateWindow(hWnd);
//idebug("class_listview >> WM_CREATE >> hwnd:%d,parent:%d,error:%d\n",h,GetParent(h), GetLastError());
//ShowWindow(h,SW_SHOW);
//UpdateWindow(h);
break;
}
case WM_NOTIFY:
{
on_notify(hWnd,wParam,lParam);
break;
}
case WM_MEASUREITEM:
{
on_measureItem(lParam);
break;
}
case WM_DRAWITEM:
{
on_drawItem(hWnd,lParam);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 2));
EndPaint(hWnd, &ps);
idebug("class_listview >> WM_PAINT->hWnd:%d,id:%d,err:%d\n", hWnd, id, GetLastError());
break;
}
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
The problem now is that i can't see other control windows except that FirstWindow can display normally.
update:
some message from debug:
class_listview >> WM_CREATE >> hWnd :1443146, className:mylistview, parent:262350,error:0
listView >> WM_SIZE >> hWnd:1443146,parent:262350
CreateListView >> rst:1,hwndlistview:853318,parent:1443146,hwndParent_:1443146, error:5
listview::init >> hWndMsgWindow:1443146,parent:262350, error:5
listview::init >> hWndListView:853318,parent:1443146,error:5
the key of the problem is the return value of WM_NOTIFY message.
i typed :
case WM_NOTIFY:
{
retnrn on_notify(hWnd,wParam,lParam);
}
the problem was resolved.
I find different examples in the Internet of how to program a PropertySheet in WinAPI, but they are not complete.
The code I am using is shown below. I have a PropertySheet with 3 Tabs, each one with a Dialog.
The different Dialogs are called, when I click the Tabs, so far it is working.
However, when I leave the PropertySheet pressing OK button, how do I get the contents in the Textboxes etc. of each Dialog?
Normally I used to do that in the DialogProc when WM_COMMAND/IDOK was received using:
GetDlgItemText( hDlg,IDC_TEXTBOX1, buf, 100);
But in the PropertySheet there is only one OK Button for all dialogs, no WM_COMMAND/IDOK is received in the DialogProc.
What shall I do?
Resource_file:
IDD_DIALOG_1 DIALOGEX 0, 0, 385, 186
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
BEGIN
LTEXT "param",IDC_STATIC,6,23,39,10
EDITTEXT IDC_TEXTBOX1,48,20,237,15
END
C Source:
LRESULT CALLBACK
Dialog1(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
char buf[500];
char* ptr;
int p; // =lParam, rin of edited person
int f;
switch (message)
{
case WM_INITDIALOG:
{
SetDlgItemText(hDlg, IDC_TEXTBOX1, "something");
return 0;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDOK: // never reached (OK Button belongs to the PropertySheet!)
}
}
}
return FALSE;
} /* Dialog1 */
INT_PTR DoPropertySheet(HWND hwndOwner, LPARAM p)
{
PROPSHEETPAGE psp[3];
PROPSHEETHEADER psh;
memset(psp,0,sizeof(psp));
for(int i=0;i<3; i++)
{
psp[i].dwSize = sizeof(PROPSHEETPAGE);
psp[i].dwFlags = PSP_USETITLE;
psp[i].hInstance = hInstance;
psp[i].lParam = p;
}
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG_1);
psp[0].pfnDlgProc = (DLGPROC)Dialog1;
psp[1].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG_2);
psp[1].pfnDlgProc = (DLGPROC)Dialog2;
psp[2].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG_3);
psp[2].pfnDlgProc = (DLGPROC)Dialog3;
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
psh.hwndParent = hwndOwner;
psh.hInstance = hInstance;
psh.pszIcon = 0;
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
psh.pfnCallback = NULL;
if (PropertySheet(&psh)) // 0:cancel, otherwise:1
{
//get contens of propertySheet here?? how??
}
return 0;
}
when user press OK or Apply all your pages got PSN_APPLY notification code. so you need look for WM_NOTIFY with PSN_APPLY code
when user press cancel you got PSN_RESET notification
INT_PTR CALLBACK PPDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
{
union {
LPARAM lp;
NMHDR* hdr;
PSHNOTIFY* psn;
};
switch (umsg)
{
case WM_NOTIFY:
lp = lParam;
switch (hdr->code)
{
case PSN_APPLY:
DbgPrint("apply");
break;
case PSN_RESET:
DbgPrint("cancel\n");
break;
}
break;
}
return 0;
}
I've started Direct2D from a very simple example.
Acquire the factory and ID2D1HwndRenderTarget, then handle WM_PAINT message to draw just a background with a solid color using "Clear" function.
It's work fine, until I start to move the window. When the window is moving it turns gray like nothing is drawing. I've tried to draw an ellipse, and the result is the same.
How could one present the window content with the window moving?
P.S. In case the code is needed
#include <Windows.h>
#include <d2d1_1.h>
#pragma comment(lib,"d2d1")
ID2D1Factory * d2factory_ptr = NULL;
ID2D1HwndRenderTarget * renderTarget_ptr = NULL;
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(
HINSTANCE hInstance
, HINSTANCE prevInstance
, LPWSTR cmd
, int nCmdShow
) {
WNDCLASSEX wndClassStruct;
ZeroMemory(&wndClassStruct, sizeof(WNDCLASSEX));
wndClassStruct.cbSize = sizeof(WNDCLASSEX);
wndClassStruct.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClassStruct.style = CS_HREDRAW | CS_VREDRAW;
wndClassStruct.hInstance = hInstance;
wndClassStruct.lpfnWndProc = mainWinProc;
wndClassStruct.lpszClassName = TEXT("MainWnd");
RegisterClassEx(&wndClassStruct);
RECT windowRect = { 0,0,640,480};
AdjustWindowRectEx(&windowRect, WS_OVERLAPPEDWINDOW, 0, WS_EX_APPWINDOW);
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, TEXT("MainWnd"), TEXT("Direct 2D Test Window"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, CW_USEDEFAULT, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, NULL, NULL, hInstance, 0);
{
D2D1_FACTORY_OPTIONS fo;
ZeroMemory(&fo, sizeof(D2D1_FACTORY_OPTIONS));
IID const factoryIID = IID_ID2D1Factory1;
HRESULT res = S_OK;
if (S_OK != (res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factoryIID, &fo, &d2factory_ptr))) {
return 0;
}
RECT clientRect;
GetClientRect(hWnd, &clientRect);
D2D1_RENDER_TARGET_PROPERTIES renderTargetProps;
ZeroMemory(&renderTargetProps, sizeof(D2D1_RENDER_TARGET_PROPERTIES));
renderTargetProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
renderTargetProps.pixelFormat = (D2D1_PIXEL_FORMAT) { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED };
renderTargetProps.dpiX = 0;
renderTargetProps.dpiY = 0;
renderTargetProps.usage = D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING;
renderTargetProps.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderProps;
ZeroMemory(&hwndRenderProps, sizeof(D2D1_HWND_RENDER_TARGET_PROPERTIES));
hwndRenderProps.hwnd = hWnd;
hwndRenderProps.pixelSize = (D2D1_SIZE_U) { clientRect.right - clientRect.left, clientRect.bottom - clientRect.top };
hwndRenderProps.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
if (S_OK != (res = d2factory_ptr->lpVtbl->CreateHwndRenderTarget(d2factory_ptr, &renderTargetProps, &hwndRenderProps, &renderTarget_ptr))) {
return 0;
}
}
ShowWindow(hWnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
if(NULL != renderTarget_ptr)
renderTarget_ptr->lpVtbl->Base.Base.Base.Release((IUnknown*)renderTarget_ptr);
if (NULL != d2factory_ptr)
d2factory_ptr->lpVtbl->Base.Release((IUnknown*)d2factory_ptr);
return 0;
}
LRESULT onPaintMainWindow() {
ID2D1RenderTargetVtbl renderTargetFuncs = renderTarget_ptr->lpVtbl->Base;
ID2D1RenderTarget * This = (ID2D1RenderTarget*)renderTarget_ptr;
D2D1_TAG tag1, tag2;
D2D1_COLOR_F backgroundClr = (D2D1_COLOR_F) { 0.0, 0.5, 1.0, 1.0 };
renderTargetFuncs.BeginDraw(This);
renderTargetFuncs.Clear(This, &backgroundClr);
renderTargetFuncs.EndDraw(This, &tag1, &tag2);
return 0;
}
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (WM_PAINT == uMsg)
return onPaintMainWindow();
if (WM_DESTROY == uMsg) {
PostQuitMessage(0); return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Configure your WNDCLASSEX to not have a background brush.
Replace this line:
wndClassStruct.hbrBackground = (HBRUSH)COLOR_WINDOW;
With this:
wndClassStruct.hbrBackground = GetStockObject(NULL_BRUSH);
Alternatively, you can modify mainWndProc to swallow the WM_ERASEBKGND messages. It achieves the same effect by not allowing the window to erase itself before issuing a WM_PAINT.
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (WM_PAINT == uMsg)
return onPaintMainWindow();
if (uMsg == WM_ERASEBKGND)
{
// ignore requests to erase the background since the wm_paint
// handler is going to redraw the entire window.
return 0;
}
if (WM_DESTROY == uMsg) {
PostQuitMessage(0); return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
i have these tow errors and can't fix them what ever i try. i am running windows 8.1
Error 1 error C3861: 'InitMainWindow': identifier not found
Error 2 error C2440: '=' : cannot convert from 'LRESULT (__stdcall *)(HWND,WPARAM,LPARAM)' to 'WNDPROC'
code:
#include <windows.h> // include the basic windows header file
bool InitMainWindow(HINSTANCE, int);
LRESULT CALLBACK MsgProc(HWND UINT, WPARAM, LPARAM);
const int width = 800;
const int height = 600;
HWND hwnd = NULL;
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if (!InitMainWindow(hInstance, nCmdShow))
return 1;
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return static_cast<int>(msg.wParam);
}
}
bool InitMainWindow(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.lpfnWndProc = MsgProc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcex.lpszClassName = NULL;
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
if (!RegisterClassEx(&wcex))
return false;
hwnd = CreateWindow (
NULL,
NULL,
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION,
GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2,
GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2,
width,
height,
(HWND)NULL,
(HMENU)NULL,
hInstance,
(LPVOID*)NULL);
if (!hwnd)
return false;
ShowWindow(hwnd, nCmdShow);
return true;
}
LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CHAR:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
You're missing a comma in your declaration of MsgProc.
You have
LRESULT CALLBACK MsgProc(HWND UINT, WPARAM, LPARAM);
which declares a function that takes an HWND named UINT.
You need
LRESULT CALLBACK MsgProc(HWND, UINT, WPARAM, LPARAM);
After this, it compiles fine.
I found that Microsoft Application Verifier is changing behavior in an unexpected way. I have a program that performs superclassing on system EDIT control. When I run it under Application Verifier with Basics/Heaps/UseLFHGuardPages=TRUE (because I'm on Windows 7 which uses Low Frag Heap), the EDIT WindowProc returns 0 (FALSE) on WM_NCCREATE, preventing the control from being created. This breaks the entire application, as it cannot go forward.
This is a minimalist source that can be used to reproduce problem on Application Verifier:
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK DialogWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
static WNDCLASS wcEDIT;
LRESULT CALLBACK EditWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
LRESULT result = CallWindowProc(wcEDIT.lpfnWndProc, hWnd, Msg, wParam, lParam);
if (Msg == WM_NCCREATE && result == 0) {
puts("UNEXPECTED: WindowProc of EDIT returned 0 (FALSE) on WM_NCCREATE");
}
return result;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASS wcDialog;
memset(&wcDialog, 0, sizeof wcDialog);
wcDialog.hInstance = hInstance;
wcDialog.lpszClassName = "MyDialog";
wcDialog.lpfnWndProc = DialogWindowProc;
wcDialog.style = CS_DBLCLKS;
if (RegisterClass(&wcDialog) == 0) {
printf("Unable to register class %s\n", wcDialog.lpszClassName);
return 0;
}
HWND hForm;
{
const char *lpClassName = wcDialog.lpszClassName;
const char *lpWindowName = NULL;
DWORD dwStyle = WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_THICKFRAME|WS_SYSMENU|WS_DLGFRAME|WS_BORDER|WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
DWORD dwExStyle = 0;
int X = 0;
int Y = 0;
int nWidth = 320;
int nHeight = 240;
HWND hWndParent = 0;
HMENU hMenu = 0;
LPVOID lpParam = NULL;
hForm = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
if (hForm == 0) {
printf("Unable to create window of class %s\n", wcDialog.lpszClassName);
return 0;
}
}
memset(&wcEDIT, 0, sizeof wcDialog);
wcEDIT.lpszClassName = "EDIT";
if (!GetClassInfo(NULL, wcEDIT.lpszClassName, &wcEDIT)) {
printf("Unable to get class info of %s\n", wcEDIT.lpszClassName);
return 0;
}
WNDCLASS wcMyEDIT;
memcpy(&wcMyEDIT, &wcEDIT, sizeof WNDCLASS);
wcMyEDIT.hInstance = hInstance;
wcMyEDIT.lpszClassName = "MyEDIT";
wcMyEDIT.lpfnWndProc = EditWindowProc;
wcMyEDIT.style |= CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
if (RegisterClass(&wcMyEDIT) == 0) {
printf("Unable to register class %s\n", wcMyEDIT.lpszClassName);
return 0;
}
HWND hEdit;
{
const char *lpClassName = wcMyEDIT.lpszClassName;
const char *lpWindowName = NULL;
DWORD dwStyle = WS_CLIPSIBLINGS|WS_CHILD|ES_AUTOVSCROLL|ES_AUTOHSCROLL;
DWORD dwExStyle = WS_EX_CLIENTEDGE;
int X = 0;
int Y = 0;
int nWidth = 121;
int nHeight = 21;
HWND hWndParent = hForm;
HMENU hMenu = 0;
LPVOID lpParam = NULL;
hEdit = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
if (hEdit == 0) {
printf("Unable to create window of class %s\n", wcMyEDIT.lpszClassName);
return 0;
}
}
puts("success");
return 0;
}