Creating/Writing File (Win32)

Heya there,

I am wondering how I can read/write a file in Win32, with the contents being stored in a variable.

As this is what I have for my button in the WM_COMMAND case...

1
2
3
4
5
6
7
hFile = CreateFile (TEXT("\\ONE.TXT"),      // Open One.txt
                      GENERIC_READ,           // Open for reading
                      0,                      // Do not share
                      NULL,                   // No security
                      OPEN_EXISTING,          // Existing file only
                      FILE_ATTRIBUTE_NORMAL,  // Normal file
                      NULL);                  // No template file 


How would I go about it?
Pass the handle returned from the "CreateFile()" function to the "ReadFile()" function: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx . The second argument in "ReadFile()" is a void pointer to a buffer where the data is stored. This one seemed too easy, am I missing something?

Here's the tutorial from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/bb540534(v=vs.85).aspx
Okay that has just sent me to a world of confusion.

With the tutorial from MSDN, I have no idea where to create the code for the actions that I need.
You would put it in the callback function that is receiving the WM_COMMAND message that you mentioned in your original post.
Okay thanks for that.

The other thing I am wondering about, is strings. Such as I can have the file name which is retrieved from an edit control, and then I could add ".txt" to the end of it.

How would I do that?
Use strcat C function or use std::string class if you want a C++ approach.
http://www.cplusplus.com/reference/clibrary/cstring/strcat/
http://www.cplusplus.com/reference/string/string/
I tried the strcat function and it returned with an error in which it cannot convert TCHAR to * Char.
u have to differentiate wide strings (chars) aka unicode and ANSI strings
u use unicode strings in function which end with "W" char like MessageBoxW()
and ANSI functions end with "A" char like MessageBoxA()

however there's TCHAR and LPTSTR chars and strings which are either unicode or ANSI (it depends on ur compiler settings)

ur problem is that u r trying to use ANSI function for wide char
use wcscat() to concatenate 2 wide strings
notice "wcs" before "cat", all functions which change string's value have "wcs" prefix:
wcslen, wcscmp, wcscpy ..
instead of strlen, strcmp, strcpy (if u don't know these functions then find decent tutorial on net before standing in win32 API waters)
Last edited on
Heya, thanks for that.

I managed to get the file creation working.I am having trouble on saving the file though, mainly because of this line...

char DataBuffer[] = szTemps;

szTemps is the variable which handles the data in the edit control.

It produces the following error...

error C2440: 'initializing' : cannot convert from 'TCHAR [128]' to 'char []'


I am confused on how to fix it.

Also when I am using wcscat() it gives me a warning saying the function may be unsafe, and to use wcscat_s() instead in which gives me the same warning?
You're building in Unicode. You need to use the macros that generates the correct concatenation.

You need to do somethin like this:
1
2
3
4
5
const size_t nSize = 512;    // size of file name string
TCHAR szFileName[nSize];   // declare file name
_tcsncpy(szFileName, szName, nSize);    // copy string from GUI into file name
_tcsncat(szFileName, _T(".txt", nSize);    // append .txt to file name
szFileName[nSize - 1] = 0;  // null terminate string encase file name is full 
Last edited on
I am kind of confused by that. Is there an easier way to explain it?

The line of code above comes from this block of code below, which is in the case for when a button is clicked.

1
2
3
4
5
6
7
8
9
10
TCHAR szTemps[128];
GetDlgItemText ( hWnd , IDC_EDIT , szTemps , 128 );

int argc;

HANDLE hFile; 
char DataBuffer[] = szTemps;
DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
The other thing I am wondering about, is strings. Such as I can have the file name which is retrieved from an edit control, and then I could add ".txt" to the end of it.


I'll try to work with the code fragments you've already posted.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fetch the name (without extension) from the screen
const DWORD dwNameSize = 128;
TCHAR szName[dwNameSize];
GetDlgItemText(hWnd, IDC_EDIT, szName, dwNameSize);

// Append the .txt extension
_tcsncat(szName, _T(.txt), dwRootNameSize);

// Create the file
HANDLE hFile = CreateFile(
    szName,      // filename
    GENERIC_READ,// Open for reading
    0,           // Do not share
    NULL,        // No security
    OPEN_EXISTING, // Existing file only
    FILE_ATTRIBUTE_NORMAL, // Normal file
    NULL);
if (hFile == INVALID_HANDLE_VALUE)
    return GetLastError();

const DWORD dwBufferSize = 64;
char szBuffer[dwBufferSize];
DWORD dwBytesRead;
ReadFile(hFile, szBuffer, dwBufferSize, dwBytesRead, NULL);

Please let me know what you don't understand.
Okay, so now I get these errors...

1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(167): error C2065: 'L' : undeclared identifier
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(167): error C2228: left of '.txt' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(167): error C2065: 'dwRootNameSize' : undeclared identifier
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(184): error C2664: 'ReadFile' : cannot convert parameter 4 from 'DWORD' to 'LPDWORD'
1>          Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast


This is the full entire code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include "resource.h"

#define ID_A 1		// Form Button
#define IDC_EDIT 2		// Edit Box
#define ID_B 3	// Checkbox
#define ID_C 4	// Group Box
#define ID_D 5	//newfilename
#define ID_E 1700

LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = CreateSolidBrush(RGB(235, 246, 252));
    wc.lpszClassName = L"WindowClass1";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
                          L"WindowClass1",    // name of the window class
                          L"Mini-Prog",   // title of the window
                          WS_OVERLAPPEDWINDOW,    // window style
                          300,    // x-position of the window
                          30,    // y-position of the window
                          700,    // width of the window
                          700,    // height of the window
                          NULL,    // we have no parent window, NULL
                          NULL,    // we aren't using menus, NULL
                          hInstance,    // application handle
                          NULL);    // used with multiple windows, NULL

    ShowWindow(hWnd, nCmdShow);

    MSG msg;

    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
	return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
		case WM_CREATE:
			{
				//Get the default font
				HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);

				HWND Gbox = CreateWindowEx(NULL,TEXT("button"), NULL,
                WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
                10, 10, 665, 640,      
                hWnd, (HMENU) ID_B, GetModuleHandle(NULL), NULL);
				SendMessage(Gbox,WM_SETFONT, (WPARAM)hfDefault,NULL);
				
				//Button
				HWND hWndButton = CreateWindowEx(NULL,TEXT("button"), TEXT("Create New File"),
                WS_CHILD | WS_VISIBLE,
                50, 60, 100, 20,      
                hWnd, (HMENU) ID_A, GetModuleHandle(NULL), NULL);
				//Button Font
				SendMessage(hWndButton,WM_SETFONT, (WPARAM)hfDefault,NULL);

				//Button
				HWND hWndnom = CreateWindowEx(NULL,TEXT("button"), TEXT("Save File"),
                WS_CHILD | WS_VISIBLE,
                50, 90, 100, 20,      
                hWnd, (HMENU) ID_E, GetModuleHandle(NULL), NULL);
				//Button Font
				SendMessage(hWndnom,WM_SETFONT, (WPARAM)hfDefault,NULL);

				// Edit Box
				HWND hWndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
											   TEXT("EDIT"),
											   NULL,
											   WS_VISIBLE | WS_CHILD | WS_VSCROLL | ES_MULTILINE,
											   200, 30, 460, 600,
											   hWnd,
											   (HMENU) IDC_EDIT,
											   GetModuleHandle(NULL),
											   NULL);

				HWND hWndnm = CreateWindowEx(WS_EX_CLIENTEDGE,
											   TEXT("EDIT"),
											   NULL,
											   WS_VISIBLE | WS_CHILD,
											   20, 30, 170, 20,
											   hWnd,
											   (HMENU) ID_D,
											   GetModuleHandle(NULL),
											   NULL);
				
				SendMessage(hWndEdit,WM_SETFONT, (WPARAM)hfDefault,NULL);
				SendMessage(hWndEdit,WM_SETTEXT,0,(LPARAM)L"Insert text here...");
			} break;

        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;

		case WM_COMMAND:
			{
				switch(LOWORD(wParam))
				{
					case ID_A://button
						{
							//MessageBox(hWnd, L"You clicked me", L"Success!", MB_ICONINFORMATION);
							TCHAR szTemp[128];
							GetDlgItemText ( hWnd , ID_D , szTemp , 128 );
							//MessageBox(hWnd, wcscat(szTemp,L".txt"), L"Success", NULL);

							if(wcslen(szTemp) == 0)
							{
								MessageBox(hWnd, L"Please enter a file name", L"New File Creation", NULL);
							}else if(wcslen(szTemp) > 0)
							{
								/*MessageBox(hWnd, wcscat(szTemp,L".txt has been created"), L"New File Creation", NULL);
								SetWindowTextA( GetDlgItem(hWnd, ID_D ), "" );

								int argc;

								HANDLE hFile; 
								char DataBuffer[] = "This is some test data to write to the file.";
					   			DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
								DWORD dwBytesWritten = 0;
								BOOL bErrorFlag = FALSE;

								hFile = CreateFile(wcscat(szTemp,L".txt"),                // name of the write
								GENERIC_WRITE,          // open for writing
								0,                      // do not share
								NULL,                   // default security
								CREATE_NEW,             // create new file only
								FILE_ATTRIBUTE_NORMAL,  // normal file
								NULL);               */   // no attr. template

								// Fetch the name (without extension) from the screen
const DWORD dwNameSize = 128;
TCHAR szName[dwNameSize];
GetDlgItemText(hWnd, IDC_EDIT, szName, dwNameSize);

// Append the .txt extension
_tcsncat(szName, _T(.txt), dwRootNameSize);

// Create the file
HANDLE hFile = CreateFile(
    szName,      // filename
    GENERIC_READ,// Open for reading
    0,           // Do not share
    NULL,        // No security
    OPEN_EXISTING, // Existing file only
    FILE_ATTRIBUTE_NORMAL, // Normal file
    NULL);
if (hFile == INVALID_HANDLE_VALUE)
    return GetLastError();

const DWORD dwBufferSize = 64;
char szBuffer[dwBufferSize];
DWORD dwBytesRead;
ReadFile(hFile, szBuffer, dwBufferSize, dwBytesRead, NULL);
							}
						}
					case ID_E:
						{
							
						}
				}
			} break;
		case WM_CLOSE:
			{
				if (MessageBox(hWnd, L"Are you sure you want to quit?", L"My application", MB_OKCANCEL) == IDOK)
	   		    {
					DestroyWindow(hWnd);
			    }
				// Else: User canceled. Do nothing.
				return 0;
			} break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}
This:
 
_tcsncat(szName, _T(.txt), dwRootNameSize);


should b:
 
_tcsncat(szName, _T(".txt"), dwRootNameSize);



And this:
 
ReadFile(hFile, szBuffer, dwBufferSize, dwBytesRead, NULL);


should be:
 
ReadFile(hFile, szBuffer, dwBufferSize, &dwBytesRead, NULL);

I ammended the lines you pointed out. Now I get this...

1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(167): error C2065: 'L' : undeclared identifier
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(167): error C2059: syntax error : 'string'
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(170): error C2228: left of '.HANDLE' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(170): error C2146: syntax error : missing ';' before identifier 'hFile'
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(181): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(181): error C2146: syntax error : missing ';' before identifier 'dwBufferSize'
1>c:\users\lostprophetpunk\documents\visual studio 2010\projects\testingground\testingground\main.cpp(183): error C2146: syntax error : missing ';' before identifier 'dwBytesRead'


It's getting a bit confusing...
Any chance of fixing the indentation and reposting what you have, I can't read that code. You can't possibly have applied the string fix and still get that error. And I can't see how you get the second error from what you've posted.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include "resource.h"

#define ID_A 1		// Form Button
#define IDC_EDIT 2		// Edit Box
#define ID_B 3	// Checkbox
#define ID_C 4	// Group Box
#define ID_D 5	//newfilename
#define ID_E 1700

LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = CreateSolidBrush(RGB(235, 246, 252));
    wc.lpszClassName = L"WindowClass1";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
                          L"WindowClass1",    // name of the window class
                          L"Mini-Prog",   // title of the window
                          WS_OVERLAPPEDWINDOW,    // window style
                          300,    // x-position of the window
                          30,    // y-position of the window
                          700,    // width of the window
                          700,    // height of the window
                          NULL,    // we have no parent window, NULL
                          NULL,    // we aren't using menus, NULL
                          hInstance,    // application handle
                          NULL);    // used with multiple windows, NULL

    ShowWindow(hWnd, nCmdShow);

    MSG msg;

    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
	return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
		case WM_CREATE:
			{
			//Get the default font
			HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);

			HWND Gbox = CreateWindowEx(NULL,TEXT("button"), NULL,
                       WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
                       10, 10, 665, 640,      
                       hWnd, (HMENU) ID_B, GetModuleHandle(NULL), NULL);
		       SendMessage(Gbox,WM_SETFONT, (WPARAM)hfDefault,NULL);
				
		       //Button
		       HWND hWndButton = CreateWindowEx(NULL,TEXT("button"), TEXT("Create New File"),
                       WS_CHILD | WS_VISIBLE,
                       50, 60, 100, 20,      
                       hWnd, (HMENU) ID_A, GetModuleHandle(NULL), NULL);
	       	      //Button Font
		      SendMessage(hWndButton,WM_SETFONT, (WPARAM)hfDefault,NULL);

		      //Button
	     	     HWND hWndnom = CreateWindowEx(NULL,TEXT("button"), TEXT("Save File"),
                     WS_CHILD | WS_VISIBLE,
                     50, 90, 100, 20,      
                     hWnd, (HMENU) ID_E, GetModuleHandle(NULL), NULL);
		     //Button Font
		     SendMessage(hWndnom,WM_SETFONT, (WPARAM)hfDefault,NULL);

		     // Edit Box
		     HWND hWndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
											   TEXT("EDIT"),
											   NULL,
											   WS_VISIBLE | WS_CHILD | WS_VSCROLL | ES_MULTILINE,
											   200, 30, 460, 600,
											   hWnd,
											   (HMENU) IDC_EDIT,
											   GetModuleHandle(NULL),
											   NULL);

		     HWND hWndnm = CreateWindowEx(WS_EX_CLIENTEDGE,
											   TEXT("EDIT"),
											   NULL,
											   WS_VISIBLE | WS_CHILD,
											   20, 30, 170, 20,
											   hWnd,
											   (HMENU) ID_D,
											   GetModuleHandle(NULL),
											   NULL);
				
		     SendMessage(hWndEdit,WM_SETFONT, (WPARAM)hfDefault,NULL);
		     SendMessage(hWndEdit,WM_SETTEXT,0,(LPARAM)L"Insert text here...");
			} break;

        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;

		case WM_COMMAND:
			{
				switch(LOWORD(wParam))
				{
					case ID_A://button
						{
							//MessageBox(hWnd, L"You clicked me", L"Success!", MB_ICONINFORMATION);
							TCHAR szTemp[128];
							GetDlgItemText ( hWnd , ID_D , szTemp , 128 );
							//MessageBox(hWnd, wcscat(szTemp,L".txt"), L"Success", NULL);

							if(wcslen(szTemp) == 0)
							{
								MessageBox(hWnd, L"Please enter a file name", L"New File Creation", NULL);
							}else if(wcslen(szTemp) > 0)
							{
								/*MessageBox(hWnd, wcscat(szTemp,L".txt has been created"), L"New File Creation", NULL);
								SetWindowTextA( GetDlgItem(hWnd, ID_D ), "" );

								int argc;

								HANDLE hFile; 
								char DataBuffer[] = "This is some test data to write to the file.";
					   			DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
								DWORD dwBytesWritten = 0;
								BOOL bErrorFlag = FALSE;

								hFile = CreateFile(wcscat(szTemp,L".txt"),                // name of the write
								GENERIC_WRITE,          // open for writing
								0,                      // do not share
								NULL,                   // default security
								CREATE_NEW,             // create new file only
								FILE_ATTRIBUTE_NORMAL,  // normal file
								NULL);               */   // no attr. template

								// Fetch the name (without extension) from the screen
                                                                const DWORD dwNameSize = 128;
                                                                TCHAR szName[dwNameSize];
                                                                GetDlgItemText(hWnd, IDC_EDIT, szName, dwNameSize);

                                                                // Append the .txt extension
                                                                _tcsncat(szName, _T(."txt"), dwRootNameSize);

                                                               // Create the file
                                                               HANDLE hFile = CreateFile(
                                                                   szName,      // filename
                                                                   GENERIC_READ,// Open for reading
                                                                   0,           // Do not share
                                                                   NULL,        // No security
                                                                   OPEN_EXISTING, // Existing file only
                                                                   FILE_ATTRIBUTE_NORMAL, // Normal file
                                                                   NULL);
                                                              if (hFile == INVALID_HANDLE_VALUE)
                                                                   return GetLastError();

                                                             const DWORD dwBufferSize = 64;
                                                             char szBuffer[dwBufferSize];
                                                             DWORD dwBytesRead;
                                                             ReadFile(hFile, szBuffer, dwBufferSize, &dwBytesRead, NULL);
							}
						}
					case ID_E:
						{
							
						}
				}
			} break;
		case WM_CLOSE:
			{
				if (MessageBox(hWnd, L"Are you sure you want to quit?", L"My application", MB_OKCANCEL) == IDOK)
	   		    {
					DestroyWindow(hWnd);
			    }
				// Else: User canceled. Do nothing.
				return 0;
			} break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}
Surely you could have fixed this yourself. The correct line is:
 
_tcsncat(szName, _T(".txt"), dwNameSize);


Some of your switch cases don't have breaks and the indentation is unhelpful.

You have transposed my entire example into your code without thinking about it, including that return statement. You will need to address that.
Last edited on
I am really confused on the saving part now. I do appreciate the help you have given me.
I know that all the examples show this one almighty switch with all the code, but consider this.

Rather than doing everything inline, why not break out specific pieces of functionality into functions?

For example, handle each message in a MessageHandler function. That way, it all gets smaller and more manageable. Then break each handler into functions based on functionality.

Also, give your resources meaningful names. If your code says ID_A, then needs a comment to say it's a button, then something's wrong with that name.

Finally, I'm not trying to write your app for you, I don't even know what you're trying to do. I'm just presenting ideas and examples of how to do it.

The example (in C++):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        doCreate(hWnd, wParam, lParam);
        break;
    case WM_DESTROY:
        doDestroy(hWnd, wParam, lParam);
        return 0;
    case WM_COMMAND:
        doCommand(hWnd, wParam, lParam);
        break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

#define ID_BUTTON_A ID_A
#define ID_EDIT_FILENAME ID_D

void doCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    const size_t nFilenameSize = 256;
    TCHAR szFilename[nFilenameSize] = "";
    DWORD dwReturn = 0;

    switch (wParam)
    {
    case ID_BUTTON_A:
        GetDlgItemText(hWnd, ID_EDIT_FILENAME, szFilename, nFilenameSize);
        if (szFilename[0] == 0)
        {
            // handle error
            // however, the button should not be enabled if there's no name
            break;
        }

        _tcscat(szFilename, _T(".txt"));
        dwReturn = doFileOperations(szFilename);
        if (dwReturn == ERROR_SUCCESS)
        {
            // handle error
            // again, the button shouldn't be enabled if the file doesn't exist
        }
        break;
    }
}

DWORD doFileOperations(LPCTSTR szFilename)
{
    HANDLE hFile = CreateFile(
        szFilename,      // filename
        GENERIC_READ,// Open for reading
        0,           // Do not share
        NULL,        // No security
        OPEN_EXISTING, // Existing file only
        FILE_ATTRIBUTE_NORMAL, // Normal file
        NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return GetLastError();

    const DWORD dwBufferSize = 64;
    char szBuffer[dwBufferSize];
    DWORD dwBytesRead;
    ReadFile(hFile, szBuffer, dwBufferSize, &dwBytesRead, NULL);

    CloseHandle(hFile);
    return ERROR_SUCCESS;
}
Last edited on
Topic archived. No new replies allowed.