Win32 API and VC++ Edit Boxes

  • (7 Pages)
  • +
  • « First
  • 5
  • 6
  • 7

98 Replies - 3946 Views - Last Post: 23 July 2012 - 10:20 AM Rate Topic: -----

#91 nullcoding  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 98
  • Joined: 08-July 12

Re: Win32 API and VC++ Edit Boxes

Posted 19 July 2012 - 11:18 AM

Forget it, I was about to edit that to say I jumped to conclusions.

Good news: This writes legibly:

				#ifdef UNICODE

				int lenBIG = GetWindowTextLength(GetDlgItem(hWnd, IDC_BIGNUM));
				wchar_t* BIGw2 = new WCHAR[lenBIG+1];
				GetDlgItemText(hWnd, IDC_BIGNUM, BIGw2, FALSE);    				
				
				wchar_t* kvalue;
				wchar_t* nvalue;
				wchar_t* formula;
				wchar_t* fractors; 
				wchar_t* dijits;

				char * cstr;

				int lenk = GetWindowTextLength(GetDlgItem(hWnd, IDC_ENTER_K));
				kvalue=new WCHAR[lenk+1];	
				int lenn = GetWindowTextLength(GetDlgItem(hWnd, IDC_ENTER_N));
				nvalue=new WCHAR[lenn+1];
				int lenf = GetWindowTextLength(GetDlgItem(hWnd, IDC_PROTH));
				formula=new WCHAR[lenf+1];
				int lenfr = GetWindowTextLength(GetDlgItem(hWnd, IDC_FACTORS));
				fractors=new WCHAR[lenfr+1];
				int lend = GetWindowTextLength(GetDlgItem(hWnd, IDC_DIGITS));
				dijits=new WCHAR[lend+1];

				std:wstring fullresults;

				GetDlgItemText(hWnd, IDC_ENTER_K, kvalue, FALSE);
				GetDlgItemText(hWnd, IDC_ENTER_N, nvalue, FALSE);
				GetDlgItemText(hWnd, IDC_PROTH, formula, FALSE);
				GetDlgItemText(hWnd, IDC_FACTORS, fractors, FALSE);
				GetDlgItemText(hWnd, IDC_DIGITS, dijits, FALSE);	

				fullresults = kvalue;
				fullresults += L" was your value of k.\n\n";
				fullresults += nvalue;
				fullresults += L" was your value of n.\n\n";
				fullresults += formula;
				fullresults += L" is the formula of this Proth number, which has ";
				fullresults += dijits;
				fullresults += L" digits.\n\n";
				fullresults += fractors;
				fullresults += L"Below is your Proth number!\r\n\r\n)";
				fullresults += BIGw2;

				const wchar_t *frchar = fullresults.c_str();

				WriteFile(
					hFile,
					frchar,
					wcslen(frchar),
					NULL,
					NULL
					);
			
			CloseHandle(hFile);

			#endif


Bad news: It only writes WORDS legibly. The numbers are, well, not numbers. Not Korean, either. But not correct.

Ought I use std::wstring for the GetDlgItemText() or what? clearly there is something a bit wrong with the way I store those values in strings. I will try some different techniques.
Was This Post Helpful? 0
  • +
  • -

#92 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 2037
  • View blog
  • Posts: 6,064
  • Joined: 05-May 12

Re: Win32 API and VC++ Edit Boxes

Posted 19 July 2012 - 11:25 AM

Functions not only help you organize code, but they also help you get rid of duplicate code.

For example, if you keep on doing something like;
int foo1 = Foo(12);
int bar1 = Bar(12);
int fizzBin1 = FizzBin(foo1 + bar1 * 2);

int foo2 = Foo(23);
int bar2 = Bar(23);
int fizzBin2 = FizzBin(foo1 + bar1 * 2);

int foo3 = Foo(91);
int bar3 = Bar(91);
int fizzBin3 = FizzBin(foo1 + bar1 * 2);



You could write a function that looks like:
int ComputeFizzBin(int x)
{
    int foo = Foo(x);
    int bar = Bar(x);
    return FizzBin(foo + bar);
}


and change your repetitive code to something easier on the eyes and the brain:
int fizzBin1 = ComputeFizzBin(12);
int fizzBin2 = ComputeFizzBin(23);
int fizzBin3 = ComputeFizzBin(91);



So that hopefully shows that this repetitive pattern can be cleaned up:
	int lenBIG = GetWindowTextLength(GetDlgItem(hWnd, IDC_BIGNUM));
	wchar_t* BIGw2 = new WCHAR[lenBIG+1];
	GetDlgItemText(hWnd, IDC_BIGNUM, BIGw2, FALSE);    				


This post has been edited by Skydiver: 19 July 2012 - 11:40 AM

Was This Post Helpful? 0
  • +
  • -

#93 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 2037
  • View blog
  • Posts: 6,064
  • Joined: 05-May 12

Re: Win32 API and VC++ Edit Boxes

Posted 19 July 2012 - 11:32 AM

A quick note: This will be a source of memory leaks:
delete [] szrem, szarem;



szarem will not be deallocated.

As I told you before, the comma operator will perform the two operation that surround it, so that code is effectively:
delete [] szrem;    // Deallocates szrem
szarem;             // This does nothing!!!



Nevermind. szarem is on the stack and so won't cause a leak.

This maybe the cause of some of your random behavior. You have code that looks like:
delete [] szrem, szarem;



But szrem is a stack variable. Never delete something that you did not allocate using new.

This post has been edited by Skydiver: 19 July 2012 - 11:42 AM

Was This Post Helpful? 0
  • +
  • -

#94 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 2037
  • View blog
  • Posts: 6,064
  • Joined: 05-May 12

Re: Win32 API and VC++ Edit Boxes

Posted 19 July 2012 - 12:43 PM

View Postnullcoding, on 19 July 2012 - 11:18 AM, said:

Forget it, I was about to edit that to say I jumped to conclusions.

Good news: This writes legibly:
Spoiler


Bad news: It only writes WORDS legibly. The numbers are, well, not numbers. Not Korean, either. But not correct.

Ought I use std::wstring for the GetDlgItemText() or what? clearly there is something a bit wrong with the way I store those values in strings. I will try some different techniques.


Sorry, I missed that post.

Set a breakpoint at line 34. In your Locals window, can you read kvalue, nvalue, formula, fractors, and digits? If so, step to the next line. Does the Locals window show the fullresults with the contents of kvalue? If so, step all the way to line 46, does frchar show the correct string?
Was This Post Helpful? 0
  • +
  • -

#95 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 2037
  • View blog
  • Posts: 6,064
  • Joined: 05-May 12

Re: Win32 API and VC++ Edit Boxes

Posted 19 July 2012 - 01:50 PM

*sigh* I know why you are getting gibbering for all the strings you are pulling from the UI.

See here:
	GetDlgItemText(hWnd, IDC_ENTER_K, kvalue, FALSE);
	GetDlgItemText(hWnd, IDC_ENTER_N, nvalue, FALSE);
	GetDlgItemText(hWnd, IDC_PROTH, formula, FALSE);
	GetDlgItemText(hWnd, IDC_FACTORS, fractors, FALSE);
	GetDlgItemText(hWnd, IDC_DIGITS, dijits, FALSE);	



The last parameter for GetDlgItemText() is the size of the buffer. Since FALSE is #define'd to be 0, you are telling Windows that the buffer size is zero. Since the buffer is supposedly zero bytes long, Windows can't even put a null terminator into the string buffer. So later in the next chunk of code, you have all the completely uninitialized string buffers for kvalue, nvalue, etc. Putting in the appropriate lenk, lenn, etc, as the last parameter should fix things.

Don't forget your BIGw2 in the code above as well.

This post has been edited by Skydiver: 19 July 2012 - 01:53 PM

Was This Post Helpful? 0
  • +
  • -

#96 nullcoding  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 98
  • Joined: 08-July 12

Re: Win32 API and VC++ Edit Boxes

Posted 23 July 2012 - 04:30 AM

Hey, me again. I decided to splinter the thread I was previously using to post the problems I kept running into with this Windows application I'm writing.

Background: It does a bunch of calculations when you click a button. Straightforward and simple (though not so much behind the scenes). Mathematically, it's perfectly stable and more or less correct. The program "works" fine.

I am still having issues with bells n' whistles, though - namely, printing to a file. There are two main issues:

1. The file has no name! No matter how I change the string for the filename, it always creates (and then overwrites) a file called ".txt" - not helpful to the user!

2. The file will sometimes be whitespaced, so instead of saying "this" it will say " t h i s ".

3. If the file doesn't put spaces all over and prints normally instead, it still cuts off at a certain point EVERY time. This is a mystery to me as well.

It seems like the program is terribly afraid of writing more than 1 KB to the file even though I specifically tell it to print the string length +1 using wcslen...

Filename stuff:

wchar_t* savenameW = new WCHAR[MAX_PATH];

<...>

				wchar_t* txt = new WCHAR[64];
				txt = L".txt.";

				int lenf = GetWindowTextLength(GetDlgItem(hWnd, IDC_PROTH));
				
				GetDlgItemText(hWnd, IDC_PROTH, savenameW, lenf+1);

				wcsncpy(savenameW, txt, 8);
										
				HANDLE hFile = CreateFile( //creates save file :)/>
				savenameW,
				GENERIC_WRITE,
				0,
				NULL,
				CREATE_ALWAYS,
				FILE_ATTRIBUTE_NORMAL,
				NULL
				);		




For reference, IDC_PROTH contains a formula determined in runtime. The dialog text is set BEFORE one clicks the "save" button. So when you click save, that box contains something like "(3*(2^5))+1" or something, which it gets as TEXT.

Clearly I have the right idea with wcsncpy, and the whole savenameW thing (sorry for my naming conventions, btw, I haven't been at this more than a week or so). So why won't it read any dialog box as input for the actual NAME of the file?

I suppose I want that answered first. We can worry about the file's formatting later. I have an inkling about why that might happen but that's a fair bit of code to post - luckily some people have already seen my code / know about my program.

Thanks in advance!

This post has been edited by nullcoding: 23 July 2012 - 04:34 AM

Was This Post Helpful? 0
  • +
  • -

#97 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 2037
  • View blog
  • Posts: 6,064
  • Joined: 05-May 12

Re: Win32 API and VC++ Edit Boxes

Posted 23 July 2012 - 05:04 AM

View Postnullcoding, on 23 July 2012 - 04:30 AM, said:

1. The file has no name! No matter how I change the string for the filename, it always creates (and then overwrites) a file called ".txt" - not helpful to the user!

This is because on line 2, you overwrite the contents of savenameW with txt. I think you meant to use wcscat() rather than wcsncpy() that you are using now.

View Postnullcoding, on 23 July 2012 - 04:30 AM, said:

2. The file will sometimes be whitespaced, so instead of saying "this" it will say " t h i s ".

3. If the file doesn't put spaces all over and prints normally instead, it still cuts off at a certain point EVERY time. This is a mystery to me as well.

It seems like the program is terribly afraid of writing more than 1 KB to the file even though I specifically tell it to print the string length +1 using wcslen...

Show us the code that saves the data to the file.

(I suspect that what you are seeing as "whitespace" is actually the the zero bytes that are the high bytes of each of the UNICODE characters.)
Was This Post Helpful? 0
  • +
  • -

#98 nullcoding  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 98
  • Joined: 08-July 12

Re: Win32 API and VC++ Edit Boxes

Posted 23 July 2012 - 07:46 AM

Thanks...I was using wcscat in the wrong places again.

So I got it to work with a file name you choose. I'd rather it got the text from one of the edit boxes and used that instead, but it doesn't like doing that (won't even make a file) so I'll focus on the file contents for now.

Here's how it writes the file.

				#ifdef UNICODE

				int lenBIG = GetWindowTextLength(GetDlgItem(hWnd, IDC_BIGNUM));
				wchar_t* BIGw2 = new WCHAR[lenBIG+1];
				GetDlgItemText(hWnd, IDC_BIGNUM, BIGw2, lenBIG+1);    				
				
				int lenk = GetWindowTextLength(GetDlgItem(hWnd, IDC_ENTER_K));
				wchar_t* kvalue=new WCHAR[lenk+1];	
				int lenn = GetWindowTextLength(GetDlgItem(hWnd, IDC_ENTER_N));
				wchar_t* nvalue=new WCHAR[lenn+1];
				int lenf = GetWindowTextLength(GetDlgItem(hWnd, IDC_PROTH));
				wchar_t* formula=new WCHAR[lenf+1];
				int lenfr = GetWindowTextLength(GetDlgItem(hWnd, IDC_FACTORS));
				wchar_t* fractors=new WCHAR[lenfr+1];
				int lend = GetWindowTextLength(GetDlgItem(hWnd, IDC_DIGITS));
				wchar_t* dijits=new WCHAR[lend+1];

				std:wstring fullresults;

				GetDlgItemText(hWnd, IDC_ENTER_K, kvalue, lenk+1);
				GetDlgItemText(hWnd, IDC_ENTER_N, nvalue, lenn+1);
				GetDlgItemText(hWnd, IDC_PROTH, formula, lenf+1);
				GetDlgItemText(hWnd, IDC_FACTORS, fractors, lenfr+1);
				GetDlgItemText(hWnd, IDC_DIGITS, dijits, lend+1);	

				fullresults = dijits;
				fullresults += L"\n\r\n";
				fullresults += kvalue;
				fullresults += L" was your value of k.\n\r\n";
				fullresults += nvalue;
				fullresults += L" was your value of n.\n\r\n";
				fullresults += formula;
				fullresults += L" is the formula of this Proth number.\n\r\n";
				fullresults += fractors;
				fullresults += L"\n\r\n\Below is your Proth number!\r\n\r\n)";
				fullresults += BIGw2;

				const wchar_t *frchar = fullresults.c_str();

				WriteFile(
					hFile,
					frchar,
					wcslen(frchar)+1,
					NULL,
					NULL
					);
			
			CloseHandle(hFile);
			break;

			#endif


Of course it can't use the formula to make a filename. The formula has a * in it. Filenames can't.

This post has been edited by nullcoding: 23 July 2012 - 08:47 AM

Was This Post Helpful? 0
  • +
  • -

#99 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 2037
  • View blog
  • Posts: 6,064
  • Joined: 05-May 12

Re: Win32 API and VC++ Edit Boxes

Posted 23 July 2012 - 10:20 AM

If you want to write out your string in UNICODE:

WriteFile() takes the number of bytes to be written out. wcslen() only returns the number of characters. Each UNICODE character takes up 2 bytes of space.

Before you write out your UNICODE string, you'll want to write out the UTF16 BOM so that most other text file readers will know that it contains UNICODE characters.
BYTE rgbBOM[] = { 0xFF, 0xFE };
WriteFile(hFile, rgbBOM, CountOf(rgbBOM), NULL, NULL);




If you want to write out your string in ANSI:

Create a buffer big enough for the ANSI string. Convert your UNICODE string to multibyte using wcstombs(). Pass the buffer in to WriteFile() and use strlen() to compute the number of bytes.

This post has been edited by Skydiver: 23 July 2012 - 10:23 AM

Was This Post Helpful? 0
  • +
  • -

  • (7 Pages)
  • +
  • « First
  • 5
  • 6
  • 7