NO

Author Topic: Windows program to copy a file  (Read 11884 times)

tpekar

  • Guest
Windows program to copy a file
« on: January 25, 2012, 10:47:48 PM »
I am trying to learn the Windows API.   Specifically, I am trying to re-write a program in Windows that prompts for an input file and an output file and copies the input file to the output file.  I have gotten the program to compile, but for some reason when I run it, the window will not display.  I compared it to another Windows program I wrote that displays a window go get variables that works, but cannot see why this one wil not work.  Any ideas on what I have done wrong would be greatly appreciated!

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #1 on: January 26, 2012, 12:26:53 AM »
Please don't be offended .... but there's a lot wrong with that program...

I'm thinking your best bet is to climb into a good tutorial and get started in the right direction...

Start here -->  http://www.winprog.org/tutorial/

Also you should download and install the Windows SDK which is a complete API reference...

From here --> http://www.microsoft.com/download/en/details.aspx?id=18950

The thing to do is to set your project aside for a few days and work through theForger's tutorial end to end... type up all the examples, do the exercises, work with the code, find out what works and what doesn't, one section at a time.  Especially do not read it only to find out how to copy a file... read it to learn Windows API programming.

On another note the formatting of your source code leaves a lot to be desired.  I found it almost impossible to read and follow...  So you need to work on that.  Windows code is complex, but proper formatting and spacing will make it much easier to follow.

Also you need to pay a lot more attenton to the return values of functions...
 
Set your Project's warning level to 2, and treat each error and warning as a problem to be dealt with.

I don't know what that whole linked list of windows thing is about but it's not what you want. 

For most everything there is an API function... To get the input and output filenames, use windows edit controls...  For the copy itself you can use CopyFile() and CopyFileProgress() ... you don't have to write these things manually, and in most cases you should not try.  Windows API is a very well developed and thought out programming interface, it's very unlikely you or I will best them.

Finally... you need to stop trying to write command line programs in Windows API... that's just going to cause you no end of frustration.  Do it the windows way... or not at all.
 
Again, no offense is intended, but the truth should help you along.
 
 
« Last Edit: January 26, 2012, 12:28:33 AM by CommonTater »

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #2 on: January 26, 2012, 12:34:14 AM »
Here is a small windows program you can take a look at for an example of form and structure...
 
It's a unicode editor and it has all the essentials of a full blown windows program.  Notice how easily it's written using API calls.  You can even compile it and try it out...
Code: [Select]
/*

Tiny Unicode Editor Example

*/
// for the compiler
#define UNICODE
#define _UNICODE
#define WIN32_DEFAULT_LIBS
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0502
#define _X86_

// Windows headers
#include <windows.h>
#include <commdlg.h>

//  PellesC headers
#include <stdlib.h>
#include <wchar.h>
#include <tchar.h>

#define BOM_FLAG 0xFFFE


// Window handles
HWND      Wind[5]; 
HINSTANCE Inst;
TCHAR     FileName[MAX_PATH]; // filename when opened
BOOL      RevBytes = 0;


// save a file
void SaveToFile(void)
  { OPENFILENAME  ofn;        // filename struct
    HANDLE        fh;         // handle for opening files
    DWORD         fs;         // size of the data
    PTCHAR        fd;         // pointer to data
    // get the filename
    memset(&ofn,0,sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner    = Wind[0];
    ofn.hInstance    = Inst;
    ofn.lpstrFilter  = _T("All Files\0*.*\0\0");   
    ofn.lpstrFile    = FileName;
    ofn.nMaxFile     = MAX_PATH;
    ofn.lpstrTitle   = L"Save your work";
    ofn.Flags        = OFN_NONETWORKBUTTON |
                       OFN_HIDEREADONLY |
                       OFN_NOTESTFILECREATE |
                       OFN_OVERWRITEPROMPT;
    if (!GetSaveFileName(&ofn))
      return;
    // get unicode adjusted file size from edit control
    fs = (SendMessage(Wind[4],WM_GETTEXTLENGTH,0,0) * sizeof(TCHAR));
    if (fs < 1)
      return;
    // create text buffer
    fd = malloc(fs);
    // get the text from the control
    SendMessage(Wind[4],WM_GETTEXT,fs,(LPARAM)fd);
    // open the file
    fh = CreateFile(FileName,GENERIC_WRITE,0,NULL,
                            CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL |
                            FILE_FLAG_WRITE_THROUGH,NULL);
    // save the file
    if (fh != INVALID_HANDLE_VALUE)
      { WriteFile(fh,fd,fs,&fs,NULL);
        CloseHandle(fh); }
    free(fd); }



// open a file
void OpenFromFile(void)
  { OPENFILENAME  ofn;        // filename struct
    HANDLE        fh;         // handle for opening files
    DWORD         fs;         // size of the data
    PTCHAR        fd;         // pointer to data
    // get the filename
    memset(&ofn,0,sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner    = Wind[0];
    ofn.hInstance    = Inst;
    ofn.lpstrFilter  = L"All Files\0*.*\0\0";   
    ofn.lpstrFile    = FileName;
    ofn.nMaxFile     = MAX_PATH;
    ofn.lpstrTitle   = L"Open a file";
    ofn.Flags        = OFN_NONETWORKBUTTON |
                       OFN_HIDEREADONLY |
                       OFN_NOTESTFILECREATE |
                       OFN_OVERWRITEPROMPT;
    if (!GetOpenFileName(&ofn))
      return;
    // open the file
    fh = CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,NULL);
    if (fh == INVALID_HANDLE_VALUE)
      { MessageBox(Wind[0],L"Error opening the file",L"OOPS!",0);
        return; }
    // get the file size
    fs = GetFileSize(fh,NULL) + sizeof(TCHAR);
    // create text buffer
    fd = malloc(fs);
    // clear to 0
    memset(fd,0,fs);
    // read from disk 
    ReadFile(fh,fd,fs,&fs,NULL);
    // close the file
    CloseHandle(fh);
    // put the text in the control
    SendMessage(Wind[4],WM_SETTEXT,fs,(LPARAM)fd);
    free(fd); }



// resize the window
VOID ResizeWindow(LPARAM lParm)
  { MoveWindow(Wind[4],60,2,LOWORD(lParm) - 62,HIWORD(lParm) - 4,1); }



// Message Loop
LRESULT CALLBACK MsgProc(HWND wnd,UINT msg,WPARAM wparm,LPARAM lparm)
  { switch (msg)
      { case WM_COMMAND :
          switch (LOWORD(wparm))
            { case 1001 :
                OpenFromFile();
                return 0;
              case 1002 :
                SaveToFile();
                return 0;
              case 1003 :
                PostMessage(Wind[0],WM_CLOSE,0,0);
                return 0;
              default :
                return DefWindowProc(wnd,msg,wparm,lparm); }
        case WM_SIZE  :
          ResizeWindow(lparm);
          return 0;
        case WM_CLOSE :         // close window
          DestroyWindow(Wind[0]); 
          return 0;
        case WM_DESTROY :       // NC Exit button
          PostQuitMessage(0);
          return 0;
        default :
          return DefWindowProc(wnd,msg,wparm,lparm); } }



// create the window
VOID CreateMainWindow(void)
  { WNDCLASS  wc;
    // register App Class
    memset(&wc,0,sizeof(wc));
    wc.style          = CS_CLASSDC;
    wc.hInstance      = Inst;
    wc.hCursor        = LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground  = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
    wc.lpfnWndProc    = &MsgProc;
    wc.lpszClassName  = L"TINY_UNICODE";
    RegisterClass(&wc);

    // create the main window
    Wind[0] = CreateWindowEx( WS_EX_CONTROLPARENT,
                    L"TINY_UNICODE",L"Tiny Unicode Editor",
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,0,500,300,NULL,NULL,Inst,NULL);
    // buttons
    Wind[1] = CreateWindow(L"BUTTON",L"Open",
                    WS_CHILD | WS_VISIBLE | BS_FLAT,
                    2,2,50,25,Wind[0],(HMENU) 1001,Inst,NULL);
    Wind[2] = CreateWindow(L"BUTTON",L"Save",
                    WS_CHILD | WS_VISIBLE | BS_FLAT,
                    2,30,50,25,Wind[0],(HMENU) 1002,Inst,NULL);
    Wind[3] = CreateWindow(L"BUTTON",L"Quit",
                    WS_CHILD | WS_VISIBLE | BS_FLAT,
                    2,60,50,25,Wind[0],(HMENU) 1003,Inst,NULL);
    // edit window
    Wind[4] = CreateWindowEx(WS_EX_CLIENTEDGE,L"EDIT",NULL,
                    WS_CHILD | WS_VISIBLE |
                    ES_MULTILINE,
                    60,2,200,200,Wind[0],NULL,Inst,NULL); 
    UpdateWindow(Wind[0]);
    ShowWindow(Wind[0],SW_SHOWNORMAL);    }



         
// Program Entry Procedure
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE pinst, LPSTR cmdl, int show)
  { MSG wmsg;
    // save instance handle
    Inst =    hinst;   
    // make the window
    CreateMainWindow();
    // dispatch window messages
    while (GetMessage(&wmsg,NULL,0,0))
      { TranslateMessage(&wmsg);
        DispatchMessage(&wmsg); }

    return 0; }
« Last Edit: January 26, 2012, 12:37:55 AM by CommonTater »

tpekar

  • Guest
Re: Windows program to copy a file
« Reply #3 on: February 08, 2012, 11:03:35 PM »
Thanks common tator for the unicode program example.  I worked with my program and have gotten it mostly working like I want.  But I want the edit box text to turn white with a red background if the program cannot open the input or output file.  The only way I have been able to do this is by placing a MessageBox after the "notfound:" label.  The program then displays the MessageBox (twice), then re-displays with the color change, error message, and sets the focus on the input or output file that it has a problem with.  I wonder, is there a simpler way?  And why does adding the MessageBox make the color change work, while it doesn't work without it?

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #4 on: February 09, 2012, 05:36:09 AM »
Oh boy...  Still that same terrible code...

Did you even look at the tutorial I linked for you?
Did you download and install the SDK so you have documentation?
Did you even bother to read my advice?

I can't help you if you aren't listening...

These are the errors and warnings from trying to compile your code...
Code: [Select]
Building COPYFILE.obj. E:\C_Code\junk\COPYFILE.C(78): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(82): warning #2216: The return value from 'strcpy' is never used.
E:\C_Code\junk\COPYFILE.C(83): warning #2027: Missing prototype for 'parseCmdLine'.
E:\C_Code\junk\COPYFILE.C(86): warning #2216: The return value from 'sprintf' is never used.
E:\C_Code\junk\COPYFILE.C(87): warning #2027: Missing prototype for 'wrtJoblog'.
E:\C_Code\junk\COPYFILE.C(87): warning #2216: The return value from 'wrtJoblog' is never used.
E:\C_Code\junk\COPYFILE.C(101): warning #2216: The return value from 'MessageBoxA' is never used.
E:\C_Code\junk\COPYFILE.C(150): warning #2027: Missing prototype for 'abortx'.
E:\C_Code\junk\COPYFILE.C(150): warning #2216: The return value from 'abortx' is never used.
E:\C_Code\junk\COPYFILE.C(160): warning #2216: The return value from 'SetWindowTextA' is never used.
E:\C_Code\junk\COPYFILE.C(161): warning #2216: The return value from 'SetFocus' is never used.
E:\C_Code\junk\COPYFILE.C(162): warning #2216: The return value from 'SendMessageA' is never used.
E:\C_Code\junk\COPYFILE.C(176): warning #2027: Missing prototype for 'abortx'.
E:\C_Code\junk\COPYFILE.C(176): warning #2216: The return value from 'abortx' is never used.
E:\C_Code\junk\COPYFILE.C(196): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(197): warning #2216: The return value from 'UpdateWindow' is never used.
E:\C_Code\junk\COPYFILE.C(199): warning #2216: The return value from 'MessageBoxA' is never used.
E:\C_Code\junk\COPYFILE.C(203): warning #2216: The return value from 'TranslateMessage' is never used.
E:\C_Code\junk\COPYFILE.C(204): warning #2216: The return value from 'DispatchMessageA' is never used.
E:\C_Code\junk\COPYFILE.C(79): warning #2118: Parameter 'hPrevInstance' is not referenced.
E:\C_Code\junk\COPYFILE.C(79): warning #2235: Not all control paths return a value.
E:\C_Code\junk\COPYFILE.C(210): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(215): warning #2216: The return value from 'sprintf' is never used.
E:\C_Code\junk\COPYFILE.C(216): warning #2216: The return value from 'endit' is never used.
E:\C_Code\junk\COPYFILE.C(219): warning #2027: Missing prototype for 'abortx'.
E:\C_Code\junk\COPYFILE.C(219): warning #2216: The return value from 'abortx' is never used.
E:\C_Code\junk\COPYFILE.C(221): warning #2027: Missing prototype for 'doProgress'.
E:\C_Code\junk\COPYFILE.C(221): warning #2216: The return value from 'doProgress' is never used.
E:\C_Code\junk\COPYFILE.C(226): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(226): error #2120: Redeclaration of 'doProgress', previously declared at E:\C_Code\junk\COPYFILE.C(221); expected 'int __cdecl function()' but found 'int __stdcall function(char *, char *)'.
E:\C_Code\junk\COPYFILE.C(226): warning #2118: Parameter 'text' is not referenced.
E:\C_Code\junk\COPYFILE.C(226): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(237): warning #2216: The return value from 'sprintf' is never used.
E:\C_Code\junk\COPYFILE.C(238): warning #2027: Missing prototype for 'wrtJoblog'.
E:\C_Code\junk\COPYFILE.C(238): warning #2216: The return value from 'wrtJoblog' is never used.
E:\C_Code\junk\COPYFILE.C(234): warning #2118: Parameter 'option' is not referenced.
E:\C_Code\junk\COPYFILE.C(226): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(245): warning #2216: The return value from 'sprintf' is never used.
E:\C_Code\junk\COPYFILE.C(246): warning #2027: Missing prototype for 'abortx'.
E:\C_Code\junk\COPYFILE.C(246): warning #2216: The return value from 'abortx' is never used.
E:\C_Code\junk\COPYFILE.C(226): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(251): error #2120: Redeclaration of 'wrtJoblog', previously declared at E:\C_Code\junk\COPYFILE.C(87); expected 'int __cdecl function()' but found 'int __stdcall function(char *)'.
E:\C_Code\junk\COPYFILE.C(251): warning #2118: Parameter 'str' is not referenced.
E:\C_Code\junk\COPYFILE.C(226): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(256): warning #2114: Local 'qrLast' is not referenced.
E:\C_Code\junk\COPYFILE.C(254): warning #2118: Parameter 'qDspAtr' is not referenced.
E:\C_Code\junk\COPYFILE.C(254): warning #2118: Parameter 'qentry' is not referenced.
E:\C_Code\junk\COPYFILE.C(272): warning #2216: The return value from 'wrtJoblog' is never used.
E:\C_Code\junk\COPYFILE.C(280): warning #2216: The return value from 'GetWindowTextA' is never used.
E:\C_Code\junk\COPYFILE.C(286): warning #2216: The return value from 'SetWindowTextA' is never used.
E:\C_Code\junk\COPYFILE.C(287): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(292): warning #2216: The return value from 'PostMessageA' is never used.
E:\C_Code\junk\COPYFILE.C(293): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(294): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(295): warning #2216: The return value from 'SetFocus' is never used.
E:\C_Code\junk\COPYFILE.C(296): warning #2216: The return value from 'SetWindowTextA' is never used.
E:\C_Code\junk\COPYFILE.C(297): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(304): warning #2216: The return value from 'PostMessageA' is never used.
E:\C_Code\junk\COPYFILE.C(305): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(306): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(307): warning #2216: The return value from 'SetFocus' is never used.
E:\C_Code\junk\COPYFILE.C(308): warning #2216: The return value from 'SetWindowTextA' is never used.
E:\C_Code\junk\COPYFILE.C(309): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(312): warning #2027: Missing prototype for 'copyFile'.
E:\C_Code\junk\COPYFILE.C(312): warning #2216: The return value from 'copyFile' is never used.
E:\C_Code\junk\COPYFILE.C(323): warning #2216: The return value from 'SetTextColor' is never used.
E:\C_Code\junk\COPYFILE.C(324): warning #2216: The return value from 'SetBkColor' is never used.
E:\C_Code\junk\COPYFILE.C(325): warning #2216: The return value from 'ShowWindow' is never used.
E:\C_Code\junk\COPYFILE.C(331): warning #2216: The return value from 'DestroyWindow' is never used.
E:\C_Code\junk\COPYFILE.C(266): warning #2114: Local 'message' is not referenced.
E:\C_Code\junk\COPYFILE.C(265): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(342): error #2120: Redeclaration of 'parseCmdLine', previously declared at E:\C_Code\junk\COPYFILE.C(83); expected 'int __cdecl function()' but found 'int __stdcall function(char *, char * *)'.
E:\C_Code\junk\COPYFILE.C(265): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(363): error #2120: Redeclaration of 'abortx', previously declared at E:\C_Code\junk\COPYFILE.C(150); expected 'int __cdecl function()' but found 'int __stdcall function(char *)'.
E:\C_Code\junk\COPYFILE.C(364): warning #2216: The return value from 'printf' is never used.
E:\C_Code\junk\COPYFILE.C(265): warning #2099: Missing type specifier; assuming 'int'.
E:\C_Code\junk\COPYFILE.C(368): warning #2117: Old-style function definition for 'copyFile'.
E:\C_Code\junk\COPYFILE.C(368): warning #2027: Missing prototype for 'copyFile'.
E:\C_Code\junk\COPYFILE.C(370): warning #2216: The return value from 'readit' is never used.
E:\C_Code\junk\COPYFILE.C(371): warning #2216: The return value from 'writit' is never used.
  *** Error code: 1 ***
Done.

Now... please do yourself the favour of settling down and actually doing the study and learning how to write both C code and windows GUI mode programs.
 

 
 
 
« Last Edit: February 09, 2012, 05:55:23 AM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Windows program to copy a file
« Reply #5 on: February 09, 2012, 11:22:16 AM »
1. Least take these lines away. Beside 3. parameter is wrong, it should be HDC.
PostMessage(entry.curr->Win,WM_CTLCOLOREDIT,(int)entry.curr->Win,(long)entry.curr->Win);

2. Change this:
Code: [Select]
...
static HBRUSH hRedBrush;
...
case WM_CTLCOLOREDIT:
if (lParam == (LPARAM)entry.curr->Win)
{
if (notFound == 1) {
//entry.curr->hdc = (HDC)wParam; // ??
SetTextColor(entry.curr->hdc, RGB(255, 255, 255)); // white
SetBkColor(entry.curr->hdc, RGB(255, 0, 0)); // red
return (LRESULT)hRedBrush;
} else {
SetTextColor((HDC)wParam, RGB(0, 0, 255)); //
SetBkColor((HDC)wParam, RGB(255, 255, 255)); // white
return (LRESULT)GetSysColorBrush(WHITE_BRUSH);
}
}
break;
...
case WM_CREATE:
hRedBrush = CreateSolidBrush(RGB(255, 0, 0));
return 0;
...
case WM_DESTROY:
DeleteObject(hRedBrush);
PostQuitMessage(0);
return 0;
and reset notFound elsewhere
Tip: Use something like entry.curr->found for fields
Use InvalidateRect(entry.curr->Win, NULL, TRUE); instead ShowWindow() pair.
And InvalidateRect(Wnd, NULL, TRUE); between file checkings IP and OP to update colors.

EDIT fix stupid errors...
« Last Edit: February 09, 2012, 08:55:56 PM by timovjl »
May the source be with you

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #6 on: February 09, 2012, 11:35:03 AM »
Here's a little quicky sample of a windows based file copier...
 
Copy any file from anyplace to anyplace (including network shares)
Multi language support in user entry areas
Copy with progress bar
Cancellable copies
 
It only copies one file per "go"... but you could dress it up with some options to make it do multiples, easily enough.
 
Download the zip, make a folder for it, unzip it and open the project in POIDE.  Compile and run...
 
This went together in about an hour and a half, so don't be surprised if there's a bug in there somplace, but it should show you the "form and style" of windows programming for this kind of task; especially the value in using Windows API calls for most everything. Note that it's less than 200 lines of source code...

 
« Last Edit: February 09, 2012, 11:39:08 AM by CommonTater »

tpekar

  • Guest
Re: Windows program to copy a file
« Reply #7 on: February 09, 2012, 04:16:01 PM »
Common Tater thanks for including the file copy program.  I will check it out.  Try changing your compile options from _stdcall to _cdecl.  It still will have warnings but it will compile and run.  What is important to me is that the program must be able to accept command line parameters to fill in the screen edit controls, and to re-display the window if the input or output file(s) cannot be opened.  I place the cursor on that edit control, place the error message on the bottom of the screen, and turn the edit control in error (input or output file) to white with a red background. 

This program would be a prototype.  Usually I need to input one or more files, do some processing, and output something else.  I need to accept command line parameters to allow for a "parent" program to select multiple files to run through the process.  For one client I converted 160,000 lab files, a daunting task if I had to enter them one at a time. 

I also included my resource file as an attachment.

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #8 on: February 09, 2012, 05:59:47 PM »
Common Tater thanks for including the file copy program.  I will check it out. 

It's an EXAMPLE of how windows programs should be written in a very modular and easily modified way.  It's not intended to be used as a real world program... it shows form and substance.
 
Quote
Try changing your compile options from _stdcall to _cdecl.

The standard for Windows GUI programs is _stdcall ... _cdecl is for console programs.  And yes it does matter since all windows API functions, including the entry point are stdcall.
 
Quote
I place the cursor on that edit control, place the error message on the bottom of the screen, and turn the edit control in error (input or output file) to white with a red background. 

The standard windows behaviour is to display a message box to the user...  This is one of many reasons I've been telling you to get with the tutorials and SDK... Windows is designed for a standardized appearance and behaviour for a reason.  It lessens the learning curve for people moving from one program to another... a listbox here behaves exactly like a listbox over there... And that's the whole point... to move from program to program easily and without causing errors.
 
If you start writing strange new things in a world of standardized behaviour you're just begging for all kinds of problems.
 
Quote
This program would be a prototype.  Usually I need to input one or more files, do some processing, and output something else.  I need to accept command line parameters to allow for a "parent" program to select multiple files to run through the process.

All the more reason to get on speed with the standard UI and it's controls. 
 
I've written playlist converters for several different clients that have handled tens of thousands of files in multiple directories... the background code is different of course, but they look pretty much like that file copy program...  In the last one I did, the user enters a start directory in the top bar... a destination directory in the lower bar and clicks Go ... Easy as pie...
 
Here's a screen shot I took of the last one while it was running...
 
 
 
 

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Windows program to copy a file
« Reply #9 on: February 09, 2012, 07:14:53 PM »
code for CommonTater's FileCopy commandline handling
Code: [Select]
LPWSTR *szArgs;
int nArgs;
...
case WM_INITDIALOG:
InitProgress(Dlg);
szArgs = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if (nArgs > 1) SetDlgItemText(Dlg, 4001, szArgs[1]);
if (nArgs > 2) SetDlgItemText(Dlg, 4003, szArgs[2]);
return 0;
For void MakeCopy(HWND Dlg)
Code: [Select]
...
if (lstrcmp(from, to) == 0)
return;
// warn if source not exists
if (!PathFileExists(from)) {
MessageBox(Dlg, L"Source file not exists ?", L"OOPS!",
MB_ICONHAND | MB_OK);
return;
}
// confirm if destination exists
if (PathFileExists(to))
if (MessageBox(Dlg, L"Target file exists: Overwrite?", L"OOPS!",
MB_ICONHAND | MB_YESNO) == IDNO)
return;
...
« Last Edit: February 09, 2012, 07:24:53 PM by timovjl »
May the source be with you

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #10 on: February 09, 2012, 07:30:55 PM »
Code: [Select]
      case WM_CTLCOLOREDIT:
         if (lParam == (LPARAM)entry.curr->Win)
         {
            if (notFound == 1) {
               //entry.curr->hdc = (HDC)wParam;   // ??
               SetTextColor(entry.curr->hdc, RGB(255, 255, 255));   // white
               SetBkColor(entry.curr->hdc, RGB(255, 0, 0));   // red
            } else {
               SetTextColor((HDC)wParam, RGB(0, 0, 255));   //
               SetBkColor((HDC)wParam, RGB(255, 255, 255));   // white
            }
            return 0;
         }
         break;

Actually WM_CTLCOLOREDIT (and it's kin) expect you to return a background brush for the control's background colour... like this...
 
Code: [Select]
// static colour control
LRESULT SetStaticColors(HDC dc,HWND win)
  { SetTextColor(dc,GetSysColor(COLOR_WINDOWTEXT));
    SetBkMode(dc,OPAQUE);
    SetBkColor(dc,GetSysColor(COLOR_WINDOW));
    return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_WINDOW)); }
 
// called from tosser as...
case WM_CTLCOLORSTATIC :
  return SetStaticColors((HDC)wParm,(HWND)lParm);
It's not really intended to be a Paint procedure... it's just looking for the fg/bg colours for a control.

 

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #11 on: February 09, 2012, 07:42:10 PM »
code for CommonTater's FileCopy commandline handling
Code: [Select]
LPWSTR *szArgs;
int nArgs;
...
      case WM_INITDIALOG:
         InitProgress(Dlg);
         szArgs = CommandLineToArgvW(GetCommandLineW(), &nArgs);
         if (nArgs > 1) SetDlgItemText(Dlg, 4001, szArgs[1]);
         if (nArgs > 2) SetDlgItemText(Dlg, 4003, szArgs[2]);
         return 0;
Yep, that'd do it.  But; I would place that code in the InitProgress() function rather than in the message tosser's switch itself.  It's not wrong to put it there... but it is a lot harder to troubleshoot a switch with live code in it.
Code: [Select]
// initialize progress bar
void InitProgress(HWND Dlg)
  { PWSTR *szArgs;
     INT nArgs;

    SendDlgItemMessage(Dlg,4005,PBM_SETRANGE,0,MAKELPARAM(0,100));
    szArgs = CommandLineToArgvW(GetCommandLineW(), &nArgs);
    if (nArgs > 1) SetDlgItemText(Dlg, 4001, szArgs[1]);
    if (nArgs > 2) SetDlgItemText(Dlg, 4003, szArgs[2]);
    EnableWindow(GetDlgItem(Dlg,IDCANCEL),0); }

 
For void MakeCopy(HWND Dlg)
Code: [Select]
...
   if (lstrcmp(from, to) == 0)
      return;
   // warn if source not exists
   if (!PathFileExists(from)) {
      MessageBox(Dlg, L"Source file not exists ?", L"OOPS!",
             MB_ICONHAND | MB_OK);
      return;
   }
   // confirm if destination exists
   if (PathFileExists(to))
      if (MessageBox(Dlg, L"Target file exists: Overwrite?", L"OOPS!",
             MB_ICONHAND | MB_YESNO) == IDNO)
         return;
...

 
Ok... good idea Timo... An obvious omission on my part.
 

However, this is developing my example...
It's not getting our OP friend to actually take and listen to any of our advice... I apologize if I'm wrong... but I get the distinct impression we're being harvested for code by someone who's really not interested in learning "the windows way" of doing things.
 
« Last Edit: February 09, 2012, 07:54:28 PM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Windows program to copy a file
« Reply #12 on: February 09, 2012, 08:24:09 PM »

Actually WM_CTLCOLOREDIT (and it's kin) expect you to return a background brush for the control's background colour... like this...
 
Code: [Select]
// static colour control
LRESULT SetStaticColors(HDC dc,HWND win)
  { SetTextColor(dc,GetSysColor(COLOR_WINDOWTEXT));
    SetBkMode(dc,OPAQUE);
    SetBkColor(dc,GetSysColor(COLOR_WINDOW));
    return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_WINDOW)); }
 
// called from tosser as...
case WM_CTLCOLORSTATIC :
  return SetStaticColors((HDC)wParm,(HWND)lParm);
It's not really intended to be a Paint procedure... it's just looking for the fg/bg colours for a control.

 
Yes my example was incorrect and works only in Win7.
May the source be with you

aardvajk

  • Guest
Re: Windows program to copy a file
« Reply #13 on: February 09, 2012, 08:35:34 PM »
However, this is developing my example...
It's not getting our OP friend to actually take and listen to any of our advice... I apologize if I'm wrong... but I get the distinct impression we're being harvested for code by someone who's really not interested in learning "the windows way" of doing things.

Playing devil's advocate, why should he bother? In practically every thread he's started the answerers have either gotten frustrated to the point of doing it for him, or have coded it straight out. If he gets his work done without any effort on his part, why shouldn't he continue either being or acting completely dumb?

Quote
Code: [Select]
// static colour control
LRESULT SetStaticColors(HDC dc,HWND win)
  { SetTextColor(dc,GetSysColor(COLOR_WINDOWTEXT));
    SetBkMode(dc,OPAQUE);
    SetBkColor(dc,GetSysColor(COLOR_WINDOW));
    return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_WINDOW)); }
 
// called from tosser as...
case WM_CTLCOLORSTATIC :
  return SetStaticColors((HDC)wParm,(HWND)lParm);
This leaks a brush everytime its called
« Last Edit: February 09, 2012, 08:40:46 PM by aardvajk »

CommonTater

  • Guest
Re: Windows program to copy a file
« Reply #14 on: February 09, 2012, 08:51:22 PM »
However, this is developing my example...
It's not getting our OP friend to actually take and listen to any of our advice... I apologize if I'm wrong... but I get the distinct impression we're being harvested for code by someone who's really not interested in learning "the windows way" of doing things.

Playing devil's advocate, why should he bother? In practically every thread he's started the answerers have either gotten frustrated to the point of doing it for him, or have coded it straight out. If he gets his work done without any effort on his part, why shouldn't he continue either being or acting completely dumb?

Quote
Code: [Select]
// static colour control
LRESULT SetStaticColors(HDC dc,HWND win)
  { SetTextColor(dc,GetSysColor(COLOR_WINDOWTEXT));
    SetBkMode(dc,OPAQUE);
    SetBkColor(dc,GetSysColor(COLOR_WINDOW));
    return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_WINDOW)); }
 
// called from tosser as...
case WM_CTLCOLORSTATIC :
  return SetStaticColors((HDC)wParm,(HWND)lParm);
This leaks a brush everytime its called

Then so does the example here...
http://msdn.microsoft.com/en-us/library/windows/desktop/bb787524(v=vs.85).aspx
 
 
Edit: Turns out you're right!  Thanks!  The example linked above does it right... my bad.


 
« Last Edit: February 09, 2012, 08:54:12 PM by CommonTater »