Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Onidle() loop stalling ??

Posted on 2003-10-24
3
Medium Priority
?
470 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 1500 total points
ID: 9618926
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
ID: 9619379
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
ID: 9619604
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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

722 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