WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, thanks for your reply, appreciate.

I have replaced the codes with the codes above. But I get 6 compile errors.

error C2065: 'openfile' : undeclared identifier

Looks like you have deleted the openfile declaration. See what happened to it. You should be able to correct errors like this.

WolfPack 491 Posting Virtuoso Team Colleague

Try this. My MFC is a bit rusty.

//load the file
if (openfile.DoModal()==IDOK) //prerecorded
{
    CWave wave;
    CString mp3FileName  = openfile.GetFileName();
    CString waveFileName  = openfile.GetFileName();
    waveFileName.Delete( waveFileName.ReverseFind( '.' ), waveFileName.GetLength() + 1 );
    waveFileName.Append( ".wav" );

    char FilePath[ MAX_PATH ] = "";
    DWORD dwLength = GetModuleFileName(NULL, FilePath, MAX_PATH);
    if (dwLength)
    {
        while (dwLength && FilePath[dwLength] != '\\')
            dwLength--;

        if (dwLength)
            FilePath[dwLength + 1] = '\0';
    }

    char command[MAX_PATH] = "";
    sprintf (command, "%s\\lame.exe --decode \"%s\" \"%s\"", FilePath, (LPCTSTR)mp3FileName, (LPCTSTR)waveFileName);

    system( command );
        wave.Load((LPCTSTR)waveFileName);
WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, thanks for your reply.

Sorry, I still dont understand. I thought the codes in your post and the codes I used yesterday are different. Forgive me if I am wrong. The codes that worked yesterday is

And, How to know it is using what bit rate? And How to change the bit rate with the sentence above?

What I marked in red were the changes you should make to have a bit rate of 96kbps. So your new command should be

sprintf (command, "%s -b 96\"%s\" \"C:\\Debug\\%s.mp3\"", "lame.exe" , filename, filename );
WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, May I ask one thing?

Where can I set the bit rate in the lame.exe?

=======================================================================
bitrate
=======================================================================
-b n

For MPEG-1 (sampling frequencies of 32, 44.1 and 48 kHz)
n = 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320

For MPEG-2 and MPEG-2.5 (sampling frequencies of 8, 11.025,
12, 16, 22.05 and 24 kHz)
n = 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160


The bitrate to be used. Default is 128 kbps MPEG1, 80 kbps MPEG2.

When used with variable bitrate encodings (VBR), -b specifies the
minimum bitrate to use. This is useful to prevent LAME VBR from
using some very aggressive compression which can cause some distortion
due to small flaws in the psycho-acoustic model.

=======================================================================
max bitrate
=======================================================================
-B n

see also option "-b" for allowed bitrates.

Maximum allowed bitrate when using VBR/ABR.

Using -B is NOT RECOMMENDED. A 128 kbps CBR bitstream, because of the
bit reservoir, can actually have frames which use as many bits as a
320 kbps frame. ABR/VBR modes minimize the use of the bit reservoir, and
thus need to allow 320 kbps frames to get the same flexability as CBR
streams.

You can set it by changing this line in the software.

sprintf (command, "%s\\lame.exe -b 96\"%s\" \"C:\\%s.mp3\"", FilePath, filename, filename);
WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, thanks for your reply, appreciate.

I have tried to replace the two lines as above, but the compile errors are still the same.

Okay Try to see if you can find it yourself. I don't have MSDN or MFC at home. Will look at it tomorrow. Good luck. Hopefully someone else will help.

WolfPack 491 Posting Virtuoso Team Colleague

Try this

char* mp3FileName  = (LPCTSTR)(openfile.GetFileName());
	char* waveFileName = (LPCTSTR)(openfile.GetFileName());
WolfPack 491 Posting Virtuoso Team Colleague

Try this code. Note however that I didn't test the code. THere maybe some error.

//load the file
CFileDialog openfile(TRUE,NULL,NULL,OFN_OVERWRITEPROMPT,"MP3 File (*.mp3)|*.mp3|");

if (openfile.DoModal()==IDOK) //prerecorded
{
	CWave wave;
	char* mp3FileName  = openfile.GetFileName(); 
	char* waveFileName = openfile.GetFileName();
	char* PeriodPos    = waveFileName + strlen(waveFileName);
    if (PeriodPos)
    {
        while (PeriodPos && (*PeriodPos) != '.')
            PeriodPos--;

        if (PeriodPos++)
            PeriodPos = "wav";
    }
	
    char FilePath[ MAX_PATH ] = "";
    DWORD dwLength = GetModuleFileName(NULL, FilePath, MAX_PATH);
    if (dwLength)
    {
        while (dwLength && FilePath[dwLength] != '\\')
            dwLength--;

        if (dwLength)
            FilePath[dwLength + 1] = '\0';
    }

    char command[MAX_PATH] = "";
    sprintf (command, "%s\\lame.exe --decode \"%s\" \"%s\"", FilePath, mp3FileName, waveFileName);
    
    system( command );
	wave.Load(waveFileName);
... // The rest is your code - WolfPack
WolfPack 491 Posting Virtuoso Team Colleague

Post the code for the PlayWave button.

WolfPack 491 Posting Virtuoso Team Colleague

For once I am with iamthwee ( that is a good tongue twister, try repeating "Iam with Iamthwee" ). Something should be done about the code tags. Even if it is not foolproof.

I earlier had a problem with the scroll bars too, but looks like the CProgramming forum does not have those troublesome scrollbars and all of the code can be viewed at once.

And also, even if code tages are used in Daniweb, sometimes the formatting is really horrible. Especially the indenting. It must be due to the Tab characters present in the code but something must be done to rectify it.

WolfPack 491 Posting Virtuoso Team Colleague

Before that, I put the lame.exe in the folder same with my C++ software folder.

Just now, I tried to put the lame.exe in C drive, same location with the location I want to save the wave file.

This is a bit troublesome isn't it? You have to copy the lame.exe file to C:\ drive if you want to use the software. And if the wave file is in another directory it will not work. A better approach will be to use GetModuleFileName to get the current module and extract the Pathname to get the installation directory. Then you can put the lame.exe in the same folder as your software and everything will work without any trouble.

char FilePath[ MAX_PATH ] = "";
    DWORD dwLength = GetModuleFileName(NULL, FilePath, MAX_PATH);
    if (dwLength)
    {
        while (dwLength && FilePath[dwLength] != '\\')
            dwLength--;

        if (dwLength)
            FilePath[dwLength + 1] = '\0';
    }

    char command[MAX_PATH] = "";
    sprintf (command, "%s\\lame.exe \"%s\" \"C:\\%s.mp3\"", FilePath, filename, filename);
    system( command );

After adding the above code, try putting the lame.exe file in the software exe file folder and see.

May I ask? Is it possible to implement codes so that the MP3 file can be converted to Wave file when button "Play wave' is clicked?

Should I use the same code as compression?
I tried to put the codes lines on the button OnPlayWave.
But, I dont think I can do it because the software prompts to select the wave to be played, not the mp3 …

WolfPack 491 Posting Virtuoso Team Colleague

1. Was there a wave file in the C: drive before?
2. Delete it again and try again. Do you still get the wave file?
3. Have you enabled the "Show extension for known file types" in "Folder Options" ?

WolfPack 491 Posting Virtuoso Team Colleague

Let's go with your example.

/*********************************************
   * math: 1/R = 1/R1 + 1/R2 + 1/R3 ... + 1/Rn  *
   * ex: 1/R = 1/400 + 1/200                    *
   * 1/R = 3/400                                *
   * R = 400/3                                  *
   * R = 133.33 ohms                            *
   **********************************************/

Can't you add it and then get it's reciprocal like this?

1/R = 1/400 + 1/200
1/R = 0.0025 + 0.005
1/R = 0.0075
R    = 1 / 0.0075
R    = 133.33333333
WolfPack 491 Posting Virtuoso Team Colleague


The same thing happened, I could see the wave files at C drive but there is no mp3 file.

Was there a wave file in the C: drive before? Delete it again and try again.

I dont know do I need to run the cmd too?

What do you mean by run the cmd? what cmd?

WolfPack 491 Posting Virtuoso Team Colleague

Yes replace

system( "lame.exe filename \"A:\filename.mp3\"" );

with the code I gave you.

WolfPack 491 Posting Virtuoso Team Colleague

Forgive me for being not clever enough :(

No I am not the one who is not clever enough. Sorry I am having a busy day at work today. Here is a version that should work.

char command[ 100 ] = "";
    sprintf (command, "%s \"%s\" \"C:\\%s.mp3\"", "lame.exe" , filename, filename );
    //std::cout << command << std::endl;
    system( command );
WolfPack 491 Posting Virtuoso Team Colleague


The problem I am having with with the algorithm of determining how to get the lowest common denominator in order to be able to easily add the fractions.

Someone suggested using Euclid's algorithm, but I don't know exactly how that would work in this situation.

Why on earth do you want the lowest common denominator to add the fractions?? Can't you just add them just like any double value?

WolfPack 491 Posting Virtuoso Team Colleague

Where did you look in? The Floppy Disk?

WolfPack 491 Posting Virtuoso Team Colleague

Change it to

system( "lame.exe filename \"A:\filename.mp3\"" );

. my mistake. sorry.

WolfPack 491 Posting Virtuoso Team Colleague

Okay. I had a look at the sourcecode. Now after this part,

try
     {
              wave.Save(savefile.GetPathName());	
              break;
     }

you will get the wave file called filename . So there are two potions for you
1. Call the system( "lame.exe filename "A:\filename.mp3" " ); after the wave.Save(savefile.GetPathName()); and you will get the mp3 file. However you fill see the black command prompt window popping up at that time.
2. Call the functions inthe DLL file to convert the wave file to MP3. You will not see the command prompt here.

In any case, since you will not be using the wav file, save it in a temporary folder in the hard disk. Otherwise you will find there is no room in the floppy disk. You can delete it later. Save the mp3 file in the floppy drive.

WolfPack 491 Posting Virtuoso Team Colleague

Send me the code for

savebuffer.save();
WolfPack 491 Posting Virtuoso Team Colleague


May I ask? Is it possible to directly convert the wave to mp3 when the children click the button "save"? I worried that the small children dont know how to do this and that. We hope to make it as simple as possible. so that they are motivated to use this software.

Yes it is possible. You will have to add additional code for the save button. Without seeing the code for the save button I can't give anymore advice.

WolfPack 491 Posting Virtuoso Team Colleague

OKay remove

|| (wave.m_buffer.GetNumSamples()!=6*16000)

This part from the above code, and try running the program. Tell me if the error stilll comes.

WolfPack 491 Posting Virtuoso Team Colleague

Here is a corrected version. All the info gets printed out. But I don't know about any side-effects.

WolfPack 491 Posting Virtuoso Team Colleague

Remove the -t option. It is not the problem either

if ((wave.GetFormat().nChannels!=1) || (wave.GetFormat().nSamplesPerSec!=16000)
|| (wave.GetFormat().wBitsPerSample!=16) ||(wave.GetFormat().wFormatTag!=1)
|| (wave.m_buffer.GetNumSamples()!=6*16000))
{
MessageBox("Unsupported File Format!");
return;
}

In the above code, I can understand what is the blue part. But i dont get what is the one in Red. I think that is where the problem occurs. Can you explain what is it respective to the wav file format?

WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, I wonder is it the little and big endian problem? So, I tried to change to "-x" but the problem is still the same.

still searching on how to fix my problem....

No it is not a little or big endian problem. Can you tell me what is the software you are using to read the wav file? maybe i can search for it's valid wav file format.

WolfPack 491 Posting Virtuoso Team Colleague

What's the top prize again? How do I enter :rolleyes:

I think it is 29 cans of soda. Shall we share?

WolfPack 491 Posting Virtuoso Team Colleague

I searched in web if I can find any reason. This is what I can find. Maybe I am wrong as I am very new to this. Correct me if I am wrong.

I don't know. You are the expert in audio.

It stated that "The wave file saved from one program can be played by other programs (such as media player). However, the wave file saved by other programs may not be opened by this program. That is because this program only check basic wave file structure. It does not support the wave file with optional wave file structure."

Okay. Try replacing the

SET OPTIONS="--decode"

line in the Convert_MP3_TO_Wav.cmd file with

SET OPTIONS="--decode -t"

.

WolfPack 491 Posting Virtuoso Team Colleague

Okay. I think you have to specify the options you want to LAME.exe in order to get the required MP3 and WAV quality. I am not much of an audio expert but I did some changes to the script files. They are attached here. You can try them and see. After running them in the sample file you gave before I got a new WAV file of the following qualities.

Bit Rate 256 kbps
Audio Sample Size 16 bits
Channels 1 ( mono )
Audio Sample Rate 16kHz
Audio Format PCM

If they are not of the required quality, I suggest you read the usage.txt file I attached in a previous reply and see what are the options that need to be set. There is a place called

SET OPTIONS=

in both the script files so you can change them and try. If you run into any difficulty just ask. Tell me how it comes along.

WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, thanks for your reply.

I have run it successfully with your latest zip file, thanks.

You are welcome. Glad it worked.

1. After the children complete their practices, they will use your codes to compress and then save in a floppy. Then, they bring the floppy to our centre on the next visits. We (Me and the therapist) need to decompress the MP3 file back to Wave file because our software is designed to play the wave.
May I know how can I decompress back? Is it a big problem?

No. It is not a problem. I have attached a decoding script in this message. Put it to the folder where the MP3 files and the lame.exe file contains and run as before. You should get the WAV files.

2. I still get the LAME_REPORT.txt which is empty, did I make any mistake? (I am just asking)

No. I put it there so that if there are any errors and messages they will be stored in that file. That was just for debugging puposes. Don't worry about it.

WolfPack 491 Posting Virtuoso Team Colleague

Yahoooo. Got it. I forgot to write it for files with spaces in the file name.
Here is a Correct version. Hope it works this time.

WolfPack 491 Posting Virtuoso Team Colleague

If the folder where you installed VCExpress is

D:\Program Files\Microsoft Visual Studio 8\Common7\IDE

and the Solution you want to build from the command line is

E:\Test\Test.sln

This will build your solution in the Release mode from the command line.

cd /D E:\Test
set path=D:\Program Files\Microsoft Visual Studio 8\Common7\IDE;%PATH%
VCExpress.exe Test.sln /build "Release"
WolfPack 491 Posting Virtuoso Team Colleague

1) When I'm even on

cout << i << ' ';

this line and press F10, it just stays there and doesn't do anything. When pressing F11 I get the ostream headerfile. The only way to get out of here is when I use Step Out.

No idea. I can move between the lines in the for loops using F10. But F11 takes me to ostream as expected.

2) When I used Step Out and get towards the code line N°19 as you say, press F11, I get back towards ostream headerfile. When using F10, it just stays in place and doesn't do anything.

No idea again.

That's what I'm not certain of anymore, I think I allready changed some settings, don't remember which ones exactly

If you want to reset the options you could try the following, BUT AT YOUR OWN RISK. I have tried it for Microsoft Office and it worked, but have not tried it for Visual Studio. Close VCExpress, open regedit and try deleting the [HKEY_CURRENT_USER\SOFTWARE\Microsoft\VCExpress] Key. and then restart VCExpress. Should reset ALL your VCExpress Settings.
If you decide to do that REMEMBER TO BACKUP YOUR REGISTRY BEFOREHAND.
Good luck. Tell me how it goes.

WolfPack 491 Posting Virtuoso Team Colleague

Sorry for the delay. I was cooking. :cheesy:
I ran your code on a Visual C++ Express that I installed just yesterday. It is still on the factory settings.
When I set the breakpoint in line number 19,

for (int i = 1; i <= 9; ++i){
		multi(i);// this is line number 19
	}

Pressing F11 will take you to the multi function. However if you press F11 where there is a line with cout, you will be taken to the ostream file. Maybe that is where you are doing wrong. For those places try F10.

WolfPack 491 Posting Virtuoso Team Colleague

Hello,

Could someone help me, I don't know how to build project with Visual C++ toolkit 2003, that project has made with Visual Studio .NET 2003 or is this generally possible.....
Any suggestions?

If you mean, you want to build a .vcproj file or .sln file from the Visual Toolkit, you can't do that.
But it maybe worth trying

cl *.cpp

or

cl *.c
WolfPack 491 Posting Virtuoso Team Colleague

HI, WolfPack. I mean it generated a file name LAME_REPORT.txt but when I opened, it is empty and nothing inside.

:eek: Beats me. It worked at my computer.
Anyway zip your code and attach it in this thread if it is too big. If a wave file is not that big, attach a sample wave file too.

WolfPack 491 Posting Virtuoso Team Colleague

What does LAME_REPORT.txt say?

WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, I have tried to implement in my current software followed the instrustions given in your post, appreciate your help.

For your info, I put the code in the OnSave so that the lame exe will be executed whenever I click the button 'Save'.

But, what happens is after I record one sentence, I click 'Save', the software prompt me for save file name and the lame.exe came out very fast and disappeared in just a blink. And, I went to check the folder, I couldnt find any .mp3 file.

I am sorry, I think I must have made some mistakes. I wonder where I did wrong. still searching...

Well without any code I can't say anything from here. So please post your code. Anyway I have attached a simple script file inside a zip file. You can extract it and put
1. All your wav files
2. Lame.exe
3. the script file Convert_To_MP3.cmd
into a single folder and double click the Script file. All the wav files in that folder will be converted to MP3 files.
If you find that enough for your requirements you can use it freely. Otherwise if you want to find the error in your code, you should post your code.

WolfPack 491 Posting Virtuoso Team Colleague

Okay since you are using lame, I will tell you how to use it.
The syntax for using lame.exe is

lame [options] inputfile [outputfile]

So say for example you want to convert the exampleinput.wav to exampleoutput.mp3.

What you have to do is this.
add the line

system( "lame.exe exampleinput.wav exampleoutput.mp3" );

into your program and compile.

put lame.exe and exampleinput.wav to the folder where you have put your program, and run your program. You should find the exampleoutput.mp3 file created inside that folder.

here is a minimal example.

int main()
{
       system( "lame.exe exampleinput.wav exampleoutput.mp3" );
return 0;
}

Compile the above program and put the lame.exe and exampleinput.wav file to the same folder where your program is. Then run it. You should see the results.
For more information refer the usage.txt file that came with the dll file. I have attached it in this post too.

WolfPack 491 Posting Virtuoso Team Colleague

Aren't just the breakpoints enough? F9 to set the breakpoint. F10 to step line by line from a breakpoint. F11 to jump in to the next function. ....

WolfPack 491 Posting Virtuoso Team Colleague

Hi, WolfPack, Sorry to disturb, May I ask?

I was confused with the dll. I just want to call the third-party software.exe to help me do the compression and decompression part. Do I need to call the dll? Or, Can I just call the .exe from my software?

Sorry for causing any confusion, I was not clear with dll before I put this thread, after I read the pdf about dll, I think that maybe I dont need to call dll but just call the exe.

Please forgive me, I apologized for the trouble caused by me.

Do you think it is possible to call any CODEC software exe from my software? Which one is easier for a newbie like me?

But, I dont know how can I do so, do you mind to give me some guidance? Please, Please forgive me for my ignorance. I try my best in doing it. Hope you can teach me some. Please.

This depends on the DLL or exe that you are using. So I can't say anything specific. But it is possible to call any DLL or EXE from another program. You could post the documentation in this thread, so that we can take a look and give any specific advice if possible.

WolfPack 491 Posting Virtuoso Team Colleague
WolfPack 491 Posting Virtuoso Team Colleague

Don't you have to give a constant value for size? The program does not even compile in my compiler.

string names[size];
WolfPack 491 Posting Virtuoso Team Colleague

-bah- Irrelevant post. Will look further.

Edit.
Looks okay at first glance.

WolfPack 491 Posting Virtuoso Team Colleague

i bet you work for microsoft.

DevCPP is not a microsoft product.

what is it with people just because something is old doenst mean its not useful.

He didn't say it is not useful, he said it is a bad compiler. And rightly so. I don't think it supports much of the features that separate C++ from C.

I dont like winxp and refuse to buy it i like dos and you know that because of this i have been able to get rid of virii that most popular (new) anti virus software cant because the virus dosent operate in dos

I use WinXP and connected to the internet 24/7, and I have never been infected with a virus to get rid of ever.

If you want me to go out and buy a new os and a new lauguage just cause its new maybee you want to buy it for me.

You dont have to buy DevCPP. It is free. Don't know if it can run in DOS though.

you must have something better to do, you know i asked for help not critisism. Dragon you might want to take a page out of tayspen's book and help people when they ask for help and your opinion when they want it

Heard about a thing called helpful critisism? If you are just a hobbyist programming in C/C++ go ahead. But don't ever think that programming in VC1.52 will look good in your resume.

WolfPack 491 Posting Virtuoso Team Colleague

This is a long shot, but looks like name mangling to me.
Are these lines included in the header file of the DLL file?

#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif


....// Your header

#ifdef __cplusplus
}
#endif
WolfPack 491 Posting Virtuoso Team Colleague

Check this exampleby Dave Sinkula. It is fairly simple. If you want a more complicated one, there is an example by me in the same thread. But I think Dave's example will do.

Edit: Looks like Dave's example will work only for overwriting the same line. Not sure though. You can find out yourself. If that is the case, maybe my example will be the only way. :sad:

WolfPack 491 Posting Virtuoso Team Colleague

I would rather use the Sleep function than the stuff from <time.h>...

Use the

clock

function. If you use the

sleep

function you will have to implement a clock function from scratch.

1. Use a rather hackish console display with <windows.h> commands
2. Use win32 -yuck
3. Use mfc - yucky
4. Use C# - yay.

A more reasonable comparison will be

1. Use a rather hackish console display with <windows.h> commands
        Adv - Simple, use C++
        Disadv - Ugly

2. Use win32 -yuck ( for newbies perhaps )
        Adv - faster, smaller executable, better control of the program, use C++
        Disadv - difficult if you don't have the guts and time

3. Use mfc
        Adv - Easier than using Win32 API, same look and feel, use C++, a lot of examples in the internet especially www.codeproject.com 
        Disadv - A slightly larger executable, less control on the program

4. Use Managed C++
        Adv - Easier than using Win32 API and perhaps MFC, same look and feel, use C++
        Disadv - Don't know much about this, but less number of examples in the net.

5. Use C# -
        Adv - None that I can think of but Iamthwee is welcome to disagree ;) 
        Disadv - Learn C#, port your C++ program to C#...
WolfPack 491 Posting Virtuoso Team Colleague
WolfPack 491 Posting Virtuoso Team Colleague

I need to do certain things when user tries to close the window. Say may be to ask him whether he actually wants to quit or not etc. That's why I cant let DefWindowProc() to handle it.

Okay. Then you have to handle the WM_CLOSE message. But even then you can do whatever you want to do in the message handler and let the message loop break to the DefWindowProc. ( like the second piece of code I posted )Anyway it is your choice. Whatever you do doesnot relate to this problem.

But that was not the point. According to what I know the flow should be like this
WM_CLOSE > DestroyWindow() > WM_DESTROY > WM_QUIT(via PostQuitMessage). After this I didn't expect to see the file in the task manager(consequently I cannot compile my program the second time bcos the file is still used by windows ). As for the delay for PostQuitMessage() I always have to end the program through my task manager otherwise it stays there forever.

That order is correct. And if you are using only the code shown in your first example, things are as you expect. But I think the problem is somehwere in the code that you have not posted. Maybe a hidden dialog box, or most probably a thread that was called by the main application is not properly uninitialized.

WolfPack 491 Posting Virtuoso Team Colleague

PostQuitMessage() only posts a WM_QUIT message to the message loop. The message loop may or may not receive the WM_QUIT message as soon as the PostQuitMesasge(0) is called.

Also as DestroyWindow does the destroying of the child windows, resources ...blah blah, there maybe a delay in that too. But I don't think it should take more than a couple of seconds. So the reason may depend on the delay you are experiencing. If it is only a small delay, then the reason must be what I explained. If not, then there must be resources still allocated to the calling thread.

Let me comment on the WM_CLOSE message also. I see that you are explicitly calling DestroyWindow at the WM_CLOSE message. This is unnecessary. If you just let the DefWindowProc handle it, it will automatically call the WM_DESTROY Message. So either you can remove the WM_CLOSE message handling part from the message loop ( if all that you do is call DestroyWindow() )

//case WM_CLOSE: Removed the WM_CLOSE handling 
//       
case WM_DESTROY:
{
      PostQuitMessage(0);
      return 0;
}
return DefWindowProc (hWnd, msg, wParam, lParam) ;

or

just insert a break like this.

case WM_CLOSE:
{
      // Do the user notification and whatever else you want to do
      //DestroyWindow(hwnd); // Commented out this function call
      break; // break to the DefWindowProc function
}

case WM_DESTROY:
{
      PostQuitMessage(0);
      return 0;
}
return DefWindowProc (hWnd, msg, wParam, lParam) ;