title: C++ Win32 FPS and DeltaTime Implementation
body: <p>I'm trying to implement FPS and DeltaTime for my program (C++ Win32). Below is the current code that I have. FPS and DeltaTime should have been implemented in the right manner. If not, please tell me how I may fix my problem.</p>
  
  <p>The current problem I am facing is how I should use DeltaTime. That is to Update and Render. And yes I did use a wrapper class.
  Before I implemented this, I was using WindowProcedure to handle my messages and I no problem with that. But now, trying to implement this is tilting me. So before I was using a back buffer and WM_PAINT to draw and I had to take in hwnd in order to draw. And updated is via input from WindowProcedure which had to take in arguments like LPARAM and WPARAM But after reading articles and forums on this topic. Update and Render is needed but they didnt have to take in hwnd for the Render Method. As for update they didnt have to take that in.</p>
  
  <p>So basically I just want to know how do I write the Update and Render Method?</p>
  
  <pre><code>bool BaseWindow::HandleMessages() {
  
      // Counts Per Second
      INT64 counts_per_sec = 0;
      QueryPerformanceFrequency( ( LARGE_INTEGER* ) &amp;counts_per_sec );
      // Seconds Per Count
      float sec_per_count = 1.0f / ( float ) counts_per_sec;
      // Pervious Time
      INT64 prev_time = 0;
      QueryPerformanceCounter( ( LARGE_INTEGER* ) &amp;prev_time );
  
      MSG message = { 0 };
  
      if ( PeekMessage( &amp;message, NULL, 0, 0, PM_REMOVE )) {
          TranslateMessage( &amp;message );
          DispatchMessage( &amp;message );
  
          if ( message.message == WM_QUIT ) {
              OnDestroy();
              return false;
          }
      }
      else {
          // Get current count
          INT64 current_time = 0;
          QueryPerformanceCounter( ( LARGE_INTEGER* ) &amp;current_time );
          // DeltaTime
          float delta_time = ( current_time - prev_time ) * sec_per_count;
  
          // Update
  
          // Render
      }
      return true;
  }
  </code></pre>
  
  <p><strong>Update</strong>
  <strong>Main.cpp</strong></p>
  
  <pre><code>#include "BaseWindow.h"
  #include "ChildWindow.h"
  
  int APIENTRY WinMain( HINSTANCE h_instance, HINSTANCE h_prev_instance, LPSTR lp_cmd_line, int n_cmd_show ) {
  
      ChildWindow child_window( h_instance, TEXT( "Child Window" ) );
      BaseWindow base_window( TEXT( "Base Window" ), child_window.ClassName() );
  
      while ( base_window.HandleMessages() );
      return 0;
  }
  </code></pre>
  
  <p><strong>AbstractWindow.h</strong></p>
  
  <pre><code>#ifndef __ABSTRACTWINDOW_H__
  #define __ABSTRACTWINDOW_H__
  #pragma once
  
  #include &lt;Windows.h&gt;
  
  class AbstractWindow {
  
      #pragma region Methods
          public:
              AbstractWindow();
              ~AbstractWindow();
  
              virtual bool Create();
                  static LRESULT CALLBACK MessageHandler( HWND, UINT, WPARAM, LPARAM );
              protected:
                  virtual LRESULT CALLBACK WindowProcedure( HWND, UINT, WPARAM, LPARAM ) = 0;
      #pragma endregion
  
      #pragma region Variables
          protected:
              HWND hwnd_;
              DWORD style_ex_;
              LPCTSTR class_name_;
              LPCTSTR window_name_;
              DWORD style_;
              int x_;
              int y_;
              int width_;
              int height_;
              HWND parent_;
              HMENU menu_;
              HINSTANCE instance_;
  
      #pragma endregion
  
  };
  #endif // !__ABSTRACTWINDOW_H__
  </code></pre>
  
  <p><strong>AbstractWindow.cpp</strong></p>
  
  <pre><code>#include "AbstractWindow.h"
  
  AbstractWindow::AbstractWindow() {}
  
  AbstractWindow::~AbstractWindow() {}
  
  bool AbstractWindow::Create() {
      // Default Create Method
  
      hwnd_ = CreateWindowEx(
          style_ex_,
          class_name_,
          window_name_,
          style_,
          x_,
          y_,
          width_,
          height_,
          parent_,
          menu_,
          instance_,
          this
          );
  
      return ( hwnd_ ? true : false );
  
  }
  
  LRESULT CALLBACK AbstractWindow::MessageHandler( HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param ) {
  
      AbstractWindow* abstract_window = 0;
  
      if ( message == WM_NCCREATE ) {
          abstract_window = ( AbstractWindow* ) ( ( LPCREATESTRUCT( l_param ) )-&gt;lpCreateParams );
          SetWindowLong( hwnd, GWL_USERDATA, long( abstract_window ) );
      }
  
      abstract_window = ( AbstractWindow * ) ( GetWindowLong( hwnd, GWL_USERDATA ) );
  
      if ( abstract_window ) {
          return abstract_window-&gt;WindowProcedure( hwnd, message, w_param, l_param );
      }
      else {
          return DefWindowProc( hwnd, message, w_param, l_param );
      }
  
  }
  </code></pre>
  
  <p><strong>BaseWindow.h</strong></p>
  
  <pre><code>#ifndef __BASEWINDOW_H__
  #define __BASEWINDOW_H__
  #pragma once
  
  #include "AbstractWindow.h"
  #include "ChildWindow.h"
  
  class BaseWindow : public AbstractWindow {
  
      #pragma region Test Methods
          private:
              void Update();
              void Render();
      #pragma endregion
  
      #pragma region Methods
          public:
              BaseWindow();
              ~BaseWindow();
  
              bool HandleMessages();
              BaseWindow( const TCHAR*, const TCHAR* );
              void Show();
              virtual LRESULT CALLBACK WindowProcedure( HWND, UINT, WPARAM, LPARAM );
              #pragma region Handles
                  private:
                      bool CreateBackBuffer( HWND );
                      bool OnPaint( HWND );
                      bool PaintManager();
                      bool OnDestroy();
              #pragma endregion
      #pragma endregion
  
      #pragma region Variables
          private:
              RECT window_rect_;              // Structure for window width and height
              int client_width_;
              int client_height_;
              POINT mouse_pos_;
              #pragma region Back Buffer
                      HDC hdc_;                   // Handle to Device Context
                      HDC back_buffer_;           // Back Buffer
                      HBITMAP bitmap_;                // Current bitmap
              #pragma endregion
      #pragma endregion
  
  };
  #endif // !__BASEWINDOW_H__
  </code></pre>
  
  <p><strong>BaseWindow.cpp</strong></p>
  
  <pre><code>#include "BaseWindow.h"
  
  BaseWindow::BaseWindow() {}
  
  BaseWindow::~BaseWindow() {}
  
  BaseWindow::BaseWindow( const TCHAR* window_name, const TCHAR* class_name ) {
  
      style_ex_ = NULL;
      class_name_ = class_name;
      window_name_ = window_name;
      style_ = WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
      x_ = CW_USEDEFAULT;
      y_ = CW_USEDEFAULT; CW_USEDEFAULT;
      width_ = CW_USEDEFAULT;
      height_ = CW_USEDEFAULT;
      parent_ = NULL;
      menu_ = NULL;
      instance_ = GetModuleHandle( NULL );
  
      Create();
      Show();
  
  }
  
  void BaseWindow::Show() {
      ShowWindow( hwnd_, SW_SHOW );
      UpdateWindow( hwnd_ );
  }
  
  LRESULT CALLBACK BaseWindow::WindowProcedure( HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param ) {
  
      switch ( message ) {
          case WM_CREATE:
              CreateBackBuffer(hwnd);
              return true;
          case WM_ERASEBKGND:
              return true;
          case WM_DESTROY:
              return OnDestroy();
          default:
              return DefWindowProc( hwnd, message, w_param, l_param );
      }
  }
  
  bool BaseWindow::HandleMessages() {
  
      // Counts Per Second
      INT64 counts_per_sec = 0;
      QueryPerformanceFrequency( ( LARGE_INTEGER* ) &amp;counts_per_sec );
      // Seconds Per Count
      float sec_per_count = 1.0f / ( float ) counts_per_sec;
      // Pervious Time
      INT64 prev_time = 0;
      QueryPerformanceCounter( ( LARGE_INTEGER* ) &amp;prev_time );
  
      MSG message = { 0 };
  
      if ( PeekMessage( &amp;message, NULL, 0, 0, PM_REMOVE ) ) {
          TranslateMessage( &amp;message );
          DispatchMessage( &amp;message );
  
          if ( message.message == WM_QUIT ) {
              OnDestroy();
              return false;
          }
      }
      else {
          // Get current count
          INT64 current_time = 0;
          QueryPerformanceCounter( ( LARGE_INTEGER* ) &amp;current_time );
          // DeltaTime
          float delta_time = ( current_time - prev_time ) * sec_per_count;
  
          // Update
  
          // Render
          // I need to call for OnPaint()
          // I need to take in hwnd
          // But how ?
          // Or do i not take in hwnd ?
          // But hoe ?
  
      }
      return true;
  }
  
  #pragma region Handles
  
  bool BaseWindow::CreateBackBuffer( HWND hwnd ) {
  
      GetClientRect( hwnd, &amp;window_rect_ );
      client_width_ = window_rect_.right;
      client_height_ = window_rect_.bottom;
  
      back_buffer_ = CreateCompatibleDC( NULL );  // Create Back Buffer
      hdc_ = GetDC( hwnd );   // Get the Device Context
      bitmap_ = CreateCompatibleBitmap( hdc_, client_width_, client_height_ );    // Create Bitmap
      SelectObject( back_buffer_, bitmap_ );  // Select Bitmap
  
      ReleaseDC( hwnd, hdc_ );    // Release
  
      return true;
  }
  
  bool BaseWindow::OnPaint( HWND hwnd ) {
  
      PAINTSTRUCT paint_struct;
  
      hdc_ = BeginPaint( hwnd_, &amp;paint_struct );      // Get the Device Context
  
      BitBlt( back_buffer_, 0, 0, client_width_, client_height_, NULL, NULL, NULL, WHITENESS );
  
      // Paint
      PaintManager();
  
      BitBlt( hdc_, 0, 0, client_width_, client_height_, back_buffer_, 0, 0, SRCCOPY );       // Display the back buff
      InvalidateRect( hwnd, NULL, true );     // Repaint the screen
  
      EndPaint( hwnd, &amp;paint_struct );
  
      return true;
  }
  
  bool BaseWindow::PaintManager() {
  
      HBRUSH brush = ( HBRUSH ) ( GetStockObject( WHITE_BRUSH ) );
      SelectObject( back_buffer_, brush );        // Select Brush
  
      Rectangle( back_buffer_, 200, 200, 500, 500 );
  
      DeleteObject( brush );
  
      return true;
  
  }
  
  bool BaseWindow::OnDestroy() {
      PostQuitMessage( 0 );
      return true;
  }
  
  #pragma endregion
  </code></pre>
  
  <p><strong>ChildWindow.h</strong></p>
  
  <pre><code>#ifndef __CHILDWINDOW_H__
  #define __CHILDWINDOW_H__
  #pragma once
  
  #include "AbstractWindow.h"
  #include "BaseWindow.h"
  
  class ChildWindow : protected WNDCLASSEX {
  
      #pragma region Methods
          public:
              ChildWindow();
              ~ChildWindow();
  
              ChildWindow( HINSTANCE, const TCHAR* );
              bool Register();
              const TCHAR* ClassName() const;
      #pragma endregion
  
  };
  #endif // !__CHILDWINDOW_H__
  </code></pre>
  
  <p><strong>ChildWindow.cpp</strong></p>
  
  <pre><code>#include "ChildWindow.h"
  
  ChildWindow::ChildWindow() {}
  
  ChildWindow::~ChildWindow() {}
  
  ChildWindow::ChildWindow( HINSTANCE h_instance, const TCHAR* class_name ) {
  
      cbSize = sizeof( WNDCLASSEX );
      style = NULL;
      lpfnWndProc = AbstractWindow::MessageHandler;
      cbClsExtra = NULL;
      cbWndExtra = NULL;
      hInstance = h_instance;
      hIcon = LoadIcon( NULL, IDI_APPLICATION );
      hCursor = LoadCursor( NULL, IDC_ARROW );
      //hbrBackground = ( HBRUSH ) ( GetStockObject( DKGRAY_BRUSH ) );
      hbrBackground = ( HBRUSH ) NULL;
      lpszMenuName = NULL;
      lpszClassName = class_name;
      hIconSm = LoadIcon( NULL, IDI_APPLICATION );
  
      Register();
  
  }
  
  bool ChildWindow::Register() {
      return ( ( RegisterClassEx( this ) ) ? true : false );
  }
  
  const TCHAR* ChildWindow::ClassName() const {
      return lpszClassName;
  }
  </code></pre>