Solved

Onidle() loop stalling ??

Posted on 2003-10-24
3
452 Views
Last Modified: 2011-09-20
I just started learning visual C++ and programming on windows xp ..  I use visual studio .net to develop.

I was playing around (learning) with idle msg looping and found some code that would allow the application to work in the background.  As a test I just tried to scroll the text around so I can test the workings of background processing..   The code i included below works fine and it does scrolls the text from left to right but unless i am moving mouse around on the window  text scroll is very choppy , it kind of stalls then goes ...etc And if i am moving the text around than there is no problem..

I don't understand why scroll is so choppy. If anyone can explain me why that happens and if there is a maybe right way to do it  , they will receive 500 points ..  Thanks.

I included the full code below

// pocetak1.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "pocetak1.h"
#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                              // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];                  // the main window class name
      PAINTSTRUCT ps;
      HDC hdc;
      HDC hdcc;
   HWND hWnd;
   char buffer;

// Forward declarations of functions included in this code module:
ATOM                        MyRegisterClass(HINSTANCE hInstance);
BOOL                        InitInstance(HINSTANCE, int);
LRESULT CALLBACK      WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK      About(HWND, UINT, WPARAM, LPARAM);

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
      WNDCLASSEX wcex;

      wcex.cbSize = sizeof(WNDCLASSEX);

      wcex.style                  = CS_HREDRAW | CS_VREDRAW;
      wcex.lpfnWndProc      = (WNDPROC)WndProc;
      wcex.cbClsExtra            = 0;
      wcex.cbWndExtra            = 0;
      wcex.hInstance            = hInstance;
      wcex.hIcon                  = LoadIcon(hInstance, (LPCTSTR)IDI_POCETAK1);
      wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
      wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName      = (LPCTSTR)IDC_POCETAK1;
      wcex.lpszClassName      = szWindowClass;
      wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

      return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND      - process the application menu
//  WM_PAINT      - Paint the main window
//  WM_DESTROY      - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
      int wmId, wmEvent;

      switch (message)
      {
      case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                  DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
                  break;
            case IDM_EXIT:
                  DestroyWindow(hWnd);
                  break;
            default:
                  return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
      case WM_PAINT:
//            hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code here...
//                  TextOut(hdc, 6, 0, "Hello, Windows!", 15);
            EndPaint(hWnd, &ps);
            break;
      case WM_DESTROY:
            PostQuitMessage(0);
            break;
      default:
            return DefWindowProc(hWnd, message, wParam, lParam);
      }
      return 0;
}

// Message handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
      switch (message)
      {
      case WM_INITDIALOG:
            return TRUE;

      case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                  EndDialog(hDlg, LOWORD(wParam));
                  return TRUE;
            }
            break;
      }
      return FALSE;
}
void OnIdle(int i)
{
//            hdc = BeginPaint(hWnd, &ps);
//_itoa(i, buffer, 10 );
                  TextOut(hdc, i, 0, "cicamaca je moja", 15);
//            EndPaint(hWnd, &ps);
//            UpdateWindow(hWnd);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
       // TODO: Place code here.
      MSG msg;
      HACCEL hAccelTable;

      // Initialize global strings
      LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
      LoadString(hInstance, IDC_POCETAK1, szWindowClass, MAX_LOADSTRING);
      MyRegisterClass(hInstance);

      // Perform application initialization:
      if (!InitInstance (hInstance, nCmdShow))
      {
            return FALSE;
      }

      hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_POCETAK1);

      hdc = BeginPaint(hWnd, &ps);

    // Message loop. Note that this has been modified to allow
    //  us to execute even if no messages are being processed.
      int i;
      i=5;
DWORD cur_time;
DWORD time_count=140;
LONGLONG next_time=0;
next_time = timeGetTime();
// prime the message structure

PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE);

// run till completed

while (msg.message!=WM_QUIT) {

// is there a message to process?

if (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE)) {

// dispatch the message

TranslateMessage(&msg);
DispatchMessage(&msg);

} else {

             // our stuff will go here!!
      
cur_time=timeGetTime();
if (cur_time>next_time) {

i++;
    OnIdle(i);

next_time += time_count;



// flag that we need to move objects again


}


     }
}
            EndPaint(hWnd, &ps);
      return (int) msg.wParam;
}

0
Comment
Question by:basara55
3 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
Comment Utility
This is a feature of background idle processing. It works only when there are no messages to application:

PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE);

while (msg.message!=WM_QUIT)
{
    if (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE)) \
    {
        // dispatch the message
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
            // our stuff will go here!!
           cur_time=timeGetTime();
           if (cur_time>next_time)
          {
               i++;
              OnIdle(i);
              next_time += time_count;
          }
     }
}

Reading this code fragment carefully, you can see that idle processing has lowest priority and is called only if message queue is empty. Moving mouse around the window causes stream of WM_MOUSEMOVE messages which are handled in application message loop. All this time idle code is not working.
This sample has no practical use, but is allows to understand Windows message model. Idle processing is used bt MFC, for example, to update some UI elements like toolbar buttons.
If your purpose is to understand messages handling in Windows application, you got this running this sample. If you want to scroll text by some acceptable way, use timer instead of idle processing.
0
 
LVL 16

Expert Comment

by:George Tokas
Comment Utility
AlexFM allready explained why the scrolling is choppy because of the messages windows processing..
Now if you want to do a smooth scrolling there are 2 ways:
1. Block any not needed message proccessing (one way Alex describing above..).
2. Since you are new to the compiler and the language I suggest to search a bit on how to do this using threads. There are many ways to create and use threads and that way you will not use the IdleLoop() function.

George.
0
 

Author Comment

by:basara55
Comment Utility
Thanks for the prompt answer , i see what you are saying about priority in the loop , I can't belive i missed it ..

AlexFM got the points ...
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now