I am a C programmer trying to learn windows programming. Specifically, I am trying to figure out how to put text to text boxes, and retrieve it to place it into a file. Also, I need to place prompts on the window. What I am looking to do is create a window and populate it, where a user can key in data that can be retrieved and placed into a file. Here is what I have gotten so far:
#include <windows.h>
#include <stdio.h>
LPSTR szClassName = "MyClass";
HINSTANCE hInstance;
LRESULT CALLBACK MyWndProc(HWND, UINT, WPARAM, LPARAM);
HWND hwndText[3];
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
WNDCLASS wnd;
MSG msg;
HWND hwnd;
hInstance = hInst;
wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
wnd.lpfnWndProc = MyWndProc;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); //default icon
wnd.hCursor = LoadCursor(NULL, IDC_ARROW); //default arrow mouse cursor
wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wnd.lpszMenuName = NULL; //no menu
wnd.lpszClassName = szClassName;
if(!RegisterClass(&wnd)) //register the WNDCLASS
{
MessageBox(NULL, "This Program Requires Windows NT",
"Error", MB_OK);
return 0;
}
hwnd = CreateWindow(szClassName,
"Window Title",
WS_OVERLAPPEDWINDOW, //basic window style
CW_USEDEFAULT,
CW_USEDEFAULT, //set starting point to default value
CW_USEDEFAULT,
CW_USEDEFAULT, //set all the dimensions to default value
NULL, //no parent window
NULL, //no menu
hInstance,
NULL); //no parameters to pass
// create a text box and store the handle
hwndText[0] = CreateWindow(
TEXT("edit"), // The class name required is edit
TEXT("Enter text here"), // Default text.
WS_VISIBLE | WS_CHILD | WS_BORDER, // the styles
100,100, // the left and top co-ordinates
300,30, // width and height
hwnd, // parent window handle
NULL, // the ID of your combobox
hInstance, // the instance of your application
NULL
); // extra bits you dont really need
hwndText[1] = CreateWindow(
TEXT("edit"), // The class name required is edit
TEXT("2nd field"), // Default text.
WS_VISIBLE | WS_CHILD | WS_BORDER , // the styles
100,200, // the left and top co-ordinates
300,30, // width and height
hwnd, // parent window handle
NULL, // the ID of your combobox
hInstance, // the instance of your application
NULL
); // extra bits you dont really need
ShowWindow(hwnd, iCmdShow); //display the window on the screen
UpdateWindow(hwnd); //make sure the window is updated correctly
while(GetMessage(&msg, NULL, 0, 0)) //message loop
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
FILE *fp;
char data[256];
switch(msg)
{
case WM_DESTROY:
GetDlgItemText(hwndText[0],1, data, 255);
fp=fopen("c:\workoutc\wikiwin.txt","w");
fprintf(fp,"%s\n",data);
fclose(fp);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
That's a pretty good start.
BTW: It is easier to select and copy code if it is put in a code box like so:
// create a text box and store the handle
hwndText[0] = CreateWindow(TEXT("edit"), // The class name required is edit
TEXT("Enter text here"), // Default text.
WS_VISIBLE | WS_CHILD | WS_BORDER, // the styles
100, 100, // the left and top co-ordinates
300, 30, // width and height
hwnd, // parent window handle
NULL, // the ID of your combobox
hInstance, // the instance of your application
NULL); // extra bits you dont really need
Do you want the text in the two boxes to write to a file all at once or after an event such as hitting the enter key while entering text?
For getting text out of an edit box --where you know it's handle-- you can use GetWindowText().
To place text in an edit bos --where you know it's handle-- you can use SetWindowText().
You will probably want to add some kind of "OK" and "CANCEL" buttons the user can click to signal they are done editing... in a multiline edit control the Enter key is consumed by the control plus it's something of a standard on Windows.
EDIT: For DMac... we were writing at the same time, so please consider my comments as being "in addition to your own". Cheers!
All at once. Perhaps with a button that says 'Update'.
Actually responding to the "OK" or "UPDATE" button is the only time data should be extracted and written/sent as that's the only time you can be reasonably sure your user is done editing.
I was able to send data to the text boxes and retrieve it using SetWindowText and GetWindowText. Thanks. How do I put a prompt to the left of the text box to let the user know what they are keying in? What's the easiest way to put a push button on the window. Also, for some reason the retrieved text is not writing to the file I opened (?).
Quote from: tpekar on June 22, 2011, 06:22:11 PM
What's the easiest way to put a push button on the window[?].
The easiest way to string up a dialog and place controls is to use the dialog editor.
The easiest way to learn this style of rapid application development is to start the Pelle's C IDE and select "Win32 Application Wizard" from the new project menu. In the wizard select "A dialog based program." You can then poke around and experiment/modify the project code.
If you want do those without doing static dialog:
QuoteHow do I put a prompt to the left of the text box to let the user know what they are keying in?
CreateWindow(TEXT("STATIC"), TEXT("Text1:"), WS_CHILD|WS_VISIBLE, 25, 100, 55, 22, hwnd, 0, hInstance, 0);
QuoteWhat's the easiest way to put a push button on the window
hWndBtn1 = CreateWindow(TEXT("BUTTON"), TEXT("Update"), WS_CHILD|WS_VISIBLE, 5, 5, 55, 22, hwnd, (HMENU)IDM_SAVE, hInstance, 0);
Thanks. I got the button and the prompt there. How do I capture the button press to act on it?
Handle WM_COMMAND like so:
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
FILE *fp;
char data[256];
switch (msg)
{
case WM_COMMAND:
{
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case ID_MY_BUTTON:
{
//TODO: button clicked write some code.
}
break;
case ID_MY_OTHER_BUTTON:
{
//TODO: button clicked write some code.
}
break;
}
}
case WM_DESTROY:
GetDlgItemText(hwndText[0], 1, data, 255);
fp = fopen("c:\workoutc\wikiwin.txt", "w");
fprintf(fp, "%s\n", data);
fclose(fp);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Thanks. everything is working now. Does anyone know how I can send the output to a network printer instead of a file?
Quote from: tpekar on June 22, 2011, 10:07:07 PM
Thanks. everything is working now. Does anyone know how I can send the output to a network printer instead of a file?
Umm... have you taken a look at the forger's WinAPI tutorial? It will probably be a huge help to you...
http://www.winprog.org/tutorial/
QuoteDoes anyone know how I can send the output to a network printer instead of a file
Example for predefined printer:
int DoPrint(HWND hWndEdit)
{
char szBuf[512];
int y;
int nRows = SendMessage(hWndEdit, EM_GETLINECOUNT, 0, 0);
if (!nRows) return 1;
HDC hDCPrn = CreateDC(NULL, "\\\\server\\printer", NULL, NULL);
if (hDCPrn)
{
if (StartDoc(hDCPrn, NULL))
{
int MaxX = GetDeviceCaps(hDCPrn, HORZRES);
int MaxY = GetDeviceCaps(hDCPrn, VERTRES);
int MinX = GetDeviceCaps(hDCPrn, PHYSICALOFFSETX);
int MinY = GetDeviceCaps(hDCPrn, PHYSICALOFFSETY);
RECT rc;
rc.left = MinX;
rc.right = MaxX;
rc.bottom = MaxY;
y = MinY;
TEXTMETRIC tm;
GetTextMetrics(hDCPrn, &tm);
if (StartPage(hDCPrn))
{
for (int nRow = 0; nRow < nRows; nRow++)
{
szBuf[0] = (char)255;
szBuf[1] = 0;
int nLen = SendMessage(hWndEdit, EM_GETLINE, nRow, (LPARAM)&szBuf);
if (nLen)
{
rc.top = y;
szBuf[nLen] = 0;
int ir = DrawText(hDCPrn, (LPSTR)&szBuf, nLen, &rc, DT_WORDBREAK | DT_EXPANDTABS);
y += ir;
}
else
y += tm.tmHeight;
if ((y + tm.tmHeight) > MaxY)
{
y = MinY;
EndPage(hDCPrn);
StartPage(hDCPrn);
}
}
EndPage(hDCPrn);
EndDoc(hDCPrn);
}
}
DeleteDC(hDCPrn);
}
return 0;
}
modify modify modify
*****************
hwndText[1] = CreateWindow(
TEXT("edit"),
TEXT("2nd field"),
/* ! */ WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE,
100,200,
300,200,
hwnd,
/* ! */ (HMENU) 123 ,
hInstance,
NULL );
case WM_DESTROY:
{
HWND editII = GetDlgItem( GetParent(hwndText[1] ) , 123 );
int length = GetWindowTextLength( editII );
char *text = ( char *)GlobalAlloc( GPTR, ( length * ( sizeof (char) ) ) + 1);
if( ! text ) { PostQuitMessage(0); return 0; }
GetWindowText( editII , text , length - 1 );
fp=fopen("wikiwin.txt","w");
fprintf(fp,"%s\n\n\n\t ok",text);
fclose(fp);
GlobalFree( text );
PostQuitMessage(0);
}
return 0;