Hello everbody

Simply put; rand() is driving me nuts.

I've been trying to get my teeth into Dev c++ (v. 4.9.9.2) for the first time and couldn't find anything anywhere which helped me anymore. Nearly all this code is IDE generated or copied from examples - I'm just trying to understand it all.

I'm tryiing to rebuild an old prog that I built with Builder_5 (I know, I know!) for personal use a long time ago.

My prog sometimes produces results which are "out-of-bounds" - look for the red bits down below - it sometimes outputs values < 1 and > 90.

The prog should (eventually) put a value in an Editbox. There are no other complaints from the compiler.

Is it perhaps because A_function() is improperly declared?

Any pointers would be appreciated.
David

#include <windows.h>
#include <time.h>

<snip>

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
  srand (time(NULL));

  HWND hwnd;               /* This is the handle for our window */
  etc, etc, . . .    
  <big snip>
  return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)                  /* handle the messages */
  {
  char A_function();

  static int len;
  static HWND hwndEdit;
  static HWND hwndButton;
  static TCHAR text[30];

    case WM_CREATE:
    {
    //the two buttons
    CreateWindow(TEXT("button"), TEXT("Beep"), 
                 WS_VISIBLE | WS_CHILD ,
                 20, 100, 80, 25,
                 hwnd, (HMENU) 1, NULL, NULL);    
    CreateWindow(TEXT("button"), TEXT("Quit"),
                 WS_VISIBLE | WS_CHILD ,
                 120, 100, 80, 25,
                 hwnd, (HMENU) 2, NULL, NULL);
    //the checkbox
    CreateWindow(TEXT("button"), TEXT("Show Title"),
                 WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
                 20, 20, 185, 35,        
                 hwnd, (HMENU) 3, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
	        CheckDlgButton(hwnd, 3, BST_CHECKED);
    //edit box
    hwndEdit = CreateWindow(TEXT("Edit"), 
                            NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
			 50, 70, 150, 20, hwnd, (HMENU) 4,//ID_EDIT,
			 NULL, NULL);
    //editbox button
    hwndButton = CreateWindow(TEXT("button"), TEXT("Set editbox"),       
		            WS_VISIBLE | WS_CHILD,  
		            250, 70, 80, 25,        
		            hwnd, (HMENU) 5/*ID_BUTTON*/, NULL, NULL);
    //test function access button
    CreateWindow(TEXT("button"), TEXT("FuncTest"), 
                 WS_VISIBLE | WS_CHILD ,
                 220, 100, 80, 25,
                 hwnd, (HMENU) 6, NULL, NULL);    

    break;
  }

  case WM_COMMAND:
  {
    if (LOWORD(wParam) == 1) {
        Beep(400, 50);
    }
    if (LOWORD(wParam) == 2) {
        PostQuitMessage(0);
    }
    if (LOWORD(wParam) == 3) {  
        BOOL checked = IsDlgButtonChecked(hwnd, 3);
        if (checked) {
	   CheckDlgButton(hwnd, 3, BST_UNCHECKED);
            SetWindowText(hwnd, TEXT(""));
        } else {
	       CheckDlgButton(hwnd, 3, BST_CHECKED);
	       SetWindowText(hwnd, "Check Box");//title);
	 }
        }
           
    if ((HIWORD(wParam) == BN_CLICKED) && (LOWORD(wParam) == 5)) {
        len = GetWindowTextLength(hwndEdit) + 1;
        GetWindowText(hwndEdit, text, len);
        SetWindowText(hwnd, text);
    }

    if (LOWORD(wParam) == 6) {
/////////////these won't work at all - and/or throw up more error messages
//        SetWindowText(hwnd, text);
//        SetWindowText(hwnd, (LPCSTR)temp);
////////////////////////////////////
//the following is an attempt to 'see' what was going on
        char temp = A_function();

        if (temp == 0)
            SetWindowText(hwnd, "null");//(LPCSTR)temp);//text);
        else
          if (temp > 0 && temp <= 45)
              SetWindowText(hwnd, "1 - 45");//(LPCSTR)temp);//text);
          else
            if (temp > 45 && temp <= 89)
                SetWindowText(hwnd, "46 - 89");
            else
              if (temp == 90)
                  SetWindowText(hwnd, "is 90");
              else
                if (temp < 0)
                    SetWindowText(hwnd, "< 0");
                else
                  if (temp > 90)
                      SetWindowText(hwnd, "> 90");
      

    }

    break;
  }


  case WM_DESTROY:
    PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
      break;
    default:                      /* for messages that we don't deal with */
      return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}//end - LRESULT CALLBACK WindowProcedure 

char A_function()//int aNum)
{
  int bNum = rand()%90;
  char globChar;
    switch (bNum)
    {

      <super snip>

    }
    return globChar;
}

Lol I hate to say it but Dev-C++ is a poor choice also, it's buggy and no longer supported as far as I know.

Code::Blocks and Visual Studio express are the best IDEs for Windows, in my opinion. VS2010 express won't let you down I'm sure.

As far as what you have posted goes, rand()%90 returns of course 0 to 89, and is it uber-important to do this using the raw Windows API? I'm sure you could use QT, wxWidgets or Winforms and you could probably understand it a lot better.

@ NathanOliver
the original prog is a very simple password generator, producing a series of (legal) random characters for use as a password. char A_Function(); simply returnes a char using a switch statement based on the int input; there are no secrets in it. I now know there are much better ways of doing this - but that original was written a very long time ago!

@all
I didn't want to start a which-IDE-is-better discussion :-) I hadn't realised that Dev was no longer supported, so I'll be taking a look at the other options which are available.

Has no-one an idea why this prog behaves this way? Could it be an 'old' IDE on a newer OS problem?

David

Oops!
char A_Function() returns char but the code tests for an int. I changed the following (no compiler errors) but still nothing gets displayed in the title bar.

if (LOWORD(wParam) == 6) {
                   char temp = A_function();

//        SetWindowText(hwnd, temp);
                   SetWindowText(hwnd, (LPCSTR)temp);

/*                   if (temp == 0)
                      SetWindowText(hwnd, "null");//(LPCSTR)temp);//text);
<snip>
                   if (temp > 90)
                      SetWindowText(hwnd, "> 90");
*/

           }

David
(now trying this with Code::Blocks)

In your callback function inside the switch statement you have char A_Function(); . What is this for?

It's a declaration for A_Function(). Placing declarations at deeper than file scope is an older style, and sometimes nonsensical, but there's not really anything wrong with it.

it sometimes outputs values < 1 and > 90

Please post a complete program that we can test. At present, I would guess that you're treating the result of A_Function as a C-style string when it's really just a single char. The result would be that any use of the value as a string would very likely produce extraneous garbage output due to the string not being properly terminated. However, it's hard to say exactly since you've judiciously snipped (the code won't compile) and included your own troubleshooting code (the problematic parts appear to have been commented out).

At the request of Narue. I only stripped out most of the standard IDE generated code leaving enough so that people could see where my code had been placed. Yes, your right, A_Function() should only return a single char.

Everything else works just fine - just the "FuncTest" button won't place anythng in the title bar.

It's a very silly, simple, nonsense program at the moment, and as I wrote in my fist post, I'm just trying to get my teeth into this new environment.

David

#include <windows.h>
#include <time.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    srand (time(NULL));


    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
    char A_function();
    static int len;
    static HWND hwndEdit;
    static HWND hwndButton;
    static TCHAR text[30];
         case WM_CREATE:
         {
         //the two buttons
           CreateWindow(TEXT("button"), TEXT("Beep"),
                              WS_VISIBLE | WS_CHILD ,
                              20, 100, 80, 25,                  
                              hwnd, (HMENU) 1, NULL, NULL);

	  CreateWindow(TEXT("button"), TEXT("Quit"),
                              WS_VISIBLE | WS_CHILD ,
                              120, 100, 80, 25,                 
                              hwnd, (HMENU) 2, NULL, NULL);
	//the checkbox
           CreateWindow(TEXT("button"), TEXT("Show Title"),
                       WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
                       20, 20, 185, 35,
                       hwnd, (HMENU) 3, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
	              CheckDlgButton(hwnd, 3, BST_CHECKED);
        //edit box
           hwndEdit = CreateWindow(TEXT("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
				50, 70, 150, 20, hwnd, (HMENU) 4,//ID_EDIT,
				NULL, NULL);
         //editbox button
           hwndButton = CreateWindow(TEXT("button"), TEXT("Set editbox"),
		                                WS_VISIBLE | WS_CHILD,
		                                250, 70, 80, 25,
		                                hwnd, (HMENU) 5, NULL, NULL);
        //test function access button
           CreateWindow(TEXT("button"), TEXT("FuncTest"),
                              WS_VISIBLE | WS_CHILD ,
                              220, 100, 80, 25,                  
                              hwnd, (HMENU) 6, NULL, NULL);

           break;
	}

         case WM_COMMAND:
         {
                if (LOWORD(wParam) == 1) {
	           Beep(400, 50);        //tone, length
                }

	       if (LOWORD(wParam) == 2) {
                  PostQuitMessage(0);
                }

                if (LOWORD(wParam) == 3) {
                    BOOL checked = IsDlgButtonChecked(hwnd, 3);
                    if (checked) {
	               CheckDlgButton(hwnd, 3, BST_UNCHECKED);
		      SetWindowText(hwnd, TEXT(""));
                    } else {
		          CheckDlgButton(hwnd, 3, BST_CHECKED);
		          SetWindowText(hwnd, "Check Box");//title);
	                  }
                }

                if ((HIWORD(wParam) == BN_CLICKED) && (LOWORD(wParam) == 5)) {
                     len = GetWindowTextLength(hwndEdit) + 1;
                     GetWindowText(hwndEdit, text, len);
                     SetWindowText(hwnd, text);
                }

                if (LOWORD(wParam) == 6) {
                    char temp = A_function();

//                    SetWindowText(hwnd, temp);
                    SetWindowText(hwnd, (LPCSTR)temp);

                }

	       break;
        }


        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

char A_function()//int aNum)
{
  int bNum = rand()%90;
  char globChar;
    switch (bNum)
    {
          case 0:globChar = '.';break;
          case 1:globChar = 'u';break;
          case 2:globChar = 'k';break;
          case 3:globChar = 'd';break;
          case 4:globChar = '6';break;
          case 5:globChar = 'L';break;
          case 6:globChar = 'T';break;
          case 7:globChar = 'ö';break;
          case 8:globChar = '<';break;
          case 9:globChar = 'Ö';break;
          case 10:globChar = 'H';break;
          case 11:globChar = '0';break;
          case 12:globChar = 'N';break;
          case 13:globChar = 'W';break;
          case 14:globChar = 't';break;
          case 15:globChar = '#';break;
          case 16:globChar = '=';break;
          case 17:globChar = '+';break;
          case 18:globChar = 'w';break;
          case 19:globChar = 'm';break;
          case 20:globChar = 'f';break;
          case 21:globChar = '8';break;
          case 22:globChar = 'M';break;
          case 23:globChar = 'V';break;
          case 24:globChar = 'ü';break;
          case 25:globChar = '>';break;
          case 26:globChar = 'Ü';break;
          case 27:globChar = '?';break;
          case 28:globChar = 'v';break;
          case 29:globChar = 'l';break;
          case 30:globChar = 'e';break;
          case 31:globChar = '7';break;
          case 32:globChar = 'R';break;
          case 33:globChar = 'Q';break;
          case 34:globChar = 'J';break;
          case 35:globChar = '-';break;
          case 36:globChar = 'x';break;
          case 37:globChar = 'n';break;
          case 38:globChar = 'g';break;
          case 39:globChar = 'U';break;
          case 40:globChar = 'X';break;
          case 41:globChar = 'Y';break;
          case 42:globChar = '+';break;
          case 43:globChar = 'E';break;
          case 44:globChar = 'C';break;
          case 45:globChar = 'j';break;
          case 46:globChar = 'c';break;
          case 47:globChar = '5';break;
          case 48:globChar = 's';break;
          case 49:globChar = ')';break;
          case 50:globChar = 'Z';break;
          case 51:globChar = '_';break;
          case 52:globChar = ',';break;
          case 53:globChar = 'y';break;
          case 54:globChar = 'o';break;
          case 55:globChar = 'h';break;
          case 56:globChar = '&';break;
          case 57:globChar = 'G';break;
          case 58:globChar = 'z';break;
          case 59:globChar = 'p';break;
          case 60:globChar = 'O';break;
          case 61:globChar = '(';break;
          case 62:globChar = '2';break;
          case 63:globChar = 'I';break;
          case 64:globChar = 'F';break;
          case 65:globChar = 'A';break;
          case 66:globChar = '9';break;
          case 67:globChar = '3';break;
          case 68:globChar = 'r';break;
          case 69:globChar = '"';break;
          case 70:globChar = 'Ä';break;
          case 71:globChar = 'q';break;
          case 72:globChar = '$';break;
          case 73:globChar = 'P';break;
          case 74:globChar = '1';break;
          case 75:globChar = 'b';break;
          case 76:globChar = '%';break;
          case 77:globChar = 'ß';break;
          case 78:globChar = ';';break;
          case 79:globChar = 'K';break;
          case 80:globChar = '§';break;
          case 81:globChar = 'B';break;
          case 82:globChar = 'i';break;
          case 83:globChar = 'a';break;
          case 84:globChar = '4';break;
          case 85:globChar = 'ä';break;
          case 86:globChar = 'S';break;
          case 87:globChar = '!';break;
          case 88:globChar = 'D';break;
          case 89:globChar = ':';break;
    }
    return globChar;
}

Edited 5 Years Ago by Dingbats: irrelevant debug code removed

Yep, my guess was correct. Change your code to use this instead:

if (LOWORD(wParam) == 6) {
    char temp[2] = {0};

    temp[0] = A_function();

    SetWindowText(hwnd, temp);
}

Thanks Narue for your answer. I wasn't sure if you could declare a function inside a function. Does that change the scope of that function to where it can only be used in the function it is declared in?

Does that change the scope of that function to where it can only be used in the function it is declared in?

Global function definitions must still be at namespace scope, which means that the top-down rule still applies. Anything that comes after the function definition can call it, because the definition also acts as a declaration. However, prior to the definition, the scope of the declaration does indeed limit where the function is visible:

#include <iostream>

int main()
{
    {
        int bar();

        // OK: bar is visible in this scope
        std::cout << bar() << '\n';
    }

    // Not OK: no declaration for bar in scope
    std::cout << bar() << '\n';
}

int foo() // This is also a declaration
{
    return 11;
}

int bar()
{
    // OK: foo is visible in this scope
    return foo();
}
This question has already been answered. Start a new discussion instead.