Thread: Continuous polling of GetDevicePowerState inside Win32 App

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    7

    Continuous polling of GetDevicePowerState inside Win32 App

    Hi I am new to Windows programming and trying to work on a VC++ Win32 Application. Basically the code displays appropriate image (WM_PAINT) in the window create (CreateWindow()) depending on the the current power state of CDRom. However I want to update the image dynamically whenever there is a change in the CDRom's power state, as long as the app is opened. Any ideas will be greatly appreciated

    Below is the code:

    Code:
    #include "stdafx.h"
    #include "ODDPWR.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
    
    // 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);
    
    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_ODDPWR, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	// Perform application initialization:
    	if (!InitInstance (hInstance, nCmdShow)) 
    	{
    		return FALSE;
    	}
    
    	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_ODDPWR);
    
    	// Main message loop:
    	while (GetMessage(&msg, NULL, 0, 0)) 
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    
    
    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_ODDPWR);
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= (LPCTSTR)IDC_ODDPWR;
    	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)
    {
       HWND hWnd;
    
       hInst = hInstance; // Store instance handle in our global variable
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW &~WS_MAXIMIZEBOX &~WS_SIZEBOX,
          CW_USEDEFAULT, 0, 405, 450, 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)
    {
    	HANDLE hDevice;               // handle to the drive to be examined 
    	BOOL fOn = TRUE;
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc,MemDC;
            HFONT hFont;
     	HBITMAP hbmp;
    
    	hDevice = CreateFile("\\\\.\\CdRom0",  // drive to open
                        GENERIC_READ | GENERIC_WRITE,  // desired access to the drive
                        FILE_SHARE_READ | // share mode
                        FILE_SHARE_WRITE, 
                        NULL,             // default security attributes
                        OPEN_EXISTING,    // disposition
                        0,                // file attributes
                        NULL);            // do not copy file attributes
    
    
    	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);
    		
    		//Code to display text message in the window
    		hFont=CreateFont(25,0,0,0,FW_MEDIUM,1,0,0,0,0,0,2,0,"SYSTEM_FIXED_FONT");
            SelectObject(hdc,hFont);
    		TextOut(hdc, 30, 1, "CURRENT ODD POWER STATUS", 25);
    		DeleteObject(SelectObject(hdc,hFont));
     
    		//Code to display CD Drive image based on the current ODD Power State
    		//while(1)
    		//{
    		if(GetDevicePowerState(hDevice,&fOn))
    		{
    		hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CDON));
    	    // Create a memory device for CD Drive Online Logo compatible with the above DC variable
    	    MemDC = CreateCompatibleDC(hdc);
            // Select the new bitmap
            SelectObject(MemDC, hbmp);
    		// Copy the bits from the memory DC (MemDC) into the current dc (hdc)
    	    BitBlt(hdc, 70, 95, 250, 250, MemDC, 0, 0, SRCCOPY);
    	    // Restore the old bitmap
    	    DeleteDC(MemDC);
    	    DeleteObject(hbmp);
    		}
    		else
    		{
            hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CDOFF));
    	    // Create a memory device for CD Drive Offline Logo compatible with the above DC variable
    	    MemDC = CreateCompatibleDC(hdc);
            // Select the new bitmap
            SelectObject(MemDC, hbmp);
    		// Copy the bits from the memory DC (MemDC) into the current dc (hdc)
    	    BitBlt(hdc, 70, 95, 250, 250, MemDC, 0, 0, SRCCOPY);
    	    // Restore the old bitmap
    	    DeleteDC(MemDC);
    	    DeleteObject(hbmp);
    		}
    		//}
    		CloseHandle(hDevice);
    		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;
    }
    Last edited by scripterJack; 07-14-2010 at 09:55 AM. Reason: Typo

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Where to start.....

    WIN32 apps are event driven.
    The callback will be called multiple times per second.
    Any variable declared in the callback (ie the CDROM handle) will only have scope (be valid) during that msg (unless declared as static etc).

    Opening the CDROM each time you get a msg (that does not require the CDROM) creates alot of unnessecary overhead.

    You are not using GDI resources correctly and unless using a .NET version of MSVC you will be leaking a lot of GDI resources.

    typically SelectObject() is used like..

    Code:
    hDefaultFont = (HFONT*) SelectObject(hDC, hNewFont);
    //use 
    //return HDC to default state
    SelectObject(hDC, hDefaultFont );
    //clean up new GDI object
    DelectObject( hNewFont);
    The DC may fail to delete if not in the default state and you can not delete a GDI object while it is selected into a DC.

    For the task at hand....

    I would use a timer msg to do this.
    Timers generate a msg each time period until you kill the timer.

    Create the mem DC when the app starts, clean it up when the app closes.
    Each timer msg determine the image to use, load it into the mem DC and call for a paint
    [InvalidateRect() followed by UpdateWindow() ]
    In the paint BitBlt() the memDC to the HDC in teh paint struct.

    Have a search here for code, I have posted these type of things before.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using String Arrays & Pointers in a Win32 App
    By CPlus in forum Windows Programming
    Replies: 9
    Last Post: 02-24-2010, 12:14 AM
  2. Adding a console window to a Win32 app
    By VirtualAce in forum Game Programming
    Replies: 7
    Last Post: 02-01-2009, 01:09 PM
  3. Help with win32 app
    By kwm32 in forum C++ Programming
    Replies: 3
    Last Post: 03-18-2004, 04:54 PM
  4. confusion win32 -console app
    By GanglyLamb in forum C Programming
    Replies: 2
    Last Post: 06-11-2003, 10:12 AM
  5. win32 and consele app.
    By master2000 in forum C++ Programming
    Replies: 5
    Last Post: 12-22-2002, 11:50 AM