SetLayeredWindowAttributes with disabled Aero - c++

I have a program that puts a transparent window on top of the desktop where a user can do some free hand drawing with the mouse. The program works fine as long as Aero is enabled but when Aero is disabled (on Windows 7) it fails - I cannot draw and the mouse doesn't change to the mouse shape I set for the window.
The code looks like this (MFC):
//=============================================================================
// PreCreateWindow
//-----------------------------------------------------------------------------
// Public function to create the window based on global properties
//=============================================================================
BOOL CDrawWnd::PreCreateWindow(CREATESTRUCT& cs)
{
HBRUSH hBgBrush = ::CreateSolidBrush(m_crBackgroundColor);
HCURSOR hcursor = NULL;
if (m_uiCursor)
hcursor = AfxGetApp()->LoadCursor(m_uiCursor);
else if (m_Cursor)
hcursor = AfxGetApp()->LoadStandardCursor(m_Cursor); // By default IDC_CROSS
try
{
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, hcursor, hBgBrush);
}
catch(.../*CResourceException ex*/)
{
/*ex.ReportError();*/
MessageBox(_T("AfxRegisterWndClass failed"));
}
return CWnd::PreCreateWindow(cs);
}
//=============================================================================
// CreateWnd
//-----------------------------------------------------------------------------
// Public function to create the window based on global properties
//=============================================================================
bool CDrawWnd::CreateWnd()
{
CreateEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, _T("WsmLayeredWindowClass"), _T("Layered Draw Window"), WS_POPUP, m_StartWndRect, NULL, NULL, NULL);
if (m_hWnd)
{
// Make this window transparent
if (!SetLayeredWindowAttributes(m_crBackgroundColor, (255 * m_Transparency) / 100, LWA_COLORKEY))
{
TRACE(_T("\nSetLayeredWindowAttributes failed: 0x%lX"), GetLastError());
}
ShowWindow(SW_SHOW);
GetWindowRect(&m_rDrawingSurface);
return true;
}
return false;
}
CDrawWnd is derived from CWnd. CDrawWnd::CreateWnd() is called to create the window. In the case it doesn't work
SetLayeredWindowAttributes(m_crBackgroundColor, (255 * m_Transparency) / 100, LWA_COLORKEY)
fails even though GetLastError() returns 0.

Related

Need to Make CDockablePane Background Transparent in c++ MFC

I'm developing an application in MFC C++ and I have derived a CDockablePane object that I can view on the main window. I need the dockable pane's background to be transparent so you can see the main window through the dockable pane.
How would I accomplish this? Thanks.
this how i create the CDockable Pane object:
if (!FeaturePane.Create("Features", this, CSize (400,500), TRUE, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
{
TRACE0("Failed to create Program window\n");
//return false; // failed to create
return FALSE;
}
i Know you can clear the background of a CDroDialog using the following code:
BOOL CDroDialog::OnInitDialog()
{
CDialog::OnInitDialog();
SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE) ^ WS_EX_LAYERED);
SetLayeredWindowAttributes(RGB(255,0,255),0, LWA_COLORKEY);
}
BOOL CDroDialog::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CRect clientRect ;
GetClientRect(&clientRect) ;
pDC->FillSolidRect(clientRect, RGB(255,0,255)) ; // paint background in magenta
//return CDialog::OnEraseBkgnd(pDC);
return FALSE;
}

SetWindowPos() cross-process DPI aware

I am creating a program that moves/resizes windows from another process with SetWindowPos(). My own program is PROCESS_PER_MONITOR_DPI_AWARE. The other programs could be anything from PROCESS_DPI_UNAWARE, PROCESS_SYSTEM_DPI_AWARE or PROCESS_PER_MONITOR_DPI_AWARE.
Because my own program is PROCESS_PER_MONITOR_DPI_AWARE, the coordinates I pass to SetWindowPos() are in physical coordinates. What I now want to do is resize the client area to a specific size in logical coordinates.
What I have tried to do is
Get the DPI of the monitor where the window is placed as screenDPI.
Get the DPI of the target window as windowDPI.
Get scaleFactor as screenDPI / windowDPI.
Scale the desired client area size by scaleFactor
Calculated the extra size for the window frame by subtracting the current client rect size from the window rect size.
This works for the most part, but when I am using two screens with different display scaling, then
the calculation of the window frame size is off if I move the window from one screen to the next.
this fails for an application that uses PROCESS_SYSTEM_DPI_AWARE, when the window is located on the secondary screen (which uses 96dpi compared to the primary screen with 120dpi). This has nothing to do with the window frame size and I am not yet sure why exactly it fails, but the target x and y coordinates are scaled up so that the window is moved offscreen.
what happens if, because of the resize, the center of the window changes the screen? Then the screenDPI will no longer be correct, right? How would I handle that case?
I know that there is also the function AdjustWindowRectExForDpi, but somehow I can't get it to work properly. What is the dpi value I am supposed to pass to it? The dpi of the target screen, the dpi of the target window or the dpi of my own program? Additionally, this function is only available from Windows 10 onwards, so how would I handle it on an older Windows client?
I would appreciate some help with this. Thanks!
What is the dpi value I am supposed to pass to it? The dpi of the target screen, the dpi of the target window or the dpi of my own program?
The DPI of the window you need to move from one screen to the next.
code sample:
#include <Windows.h>
LRESULT CALLBACK startup_window_procedure(HWND window, UINT message, WPARAM w_param, LPARAM l_param)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_DPICHANGED:
{
// Resize the window
RECT* new_rect = reinterpret_cast<RECT*>(l_param);
if (!SetWindowPos(window, nullptr, new_rect->left, new_rect->top, new_rect->right - new_rect->left, new_rect->bottom - new_rect->top, SWP_NOZORDER | SWP_NOACTIVATE))
{
return 1;
}
return 0;
}
}
return DefWindowProcW(window, message, w_param, l_param);
}
int CALLBACK wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR cmd_line, int cmd_show)
{
constexpr auto window_class_name = L"example_dialog";
constexpr auto window_style = WS_OVERLAPPEDWINDOW;
// Enable per-monitor DPI-awareness version 2
if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
{
return 1;
}
// Create the window
WNDCLASSEXW window_class;
window_class.cbSize = sizeof(window_class);
window_class.style = CS_HREDRAW | CS_VREDRAW;
window_class.lpfnWndProc = startup_window_procedure;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = instance;
window_class.hIcon = nullptr;
window_class.hCursor = nullptr;
window_class.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
window_class.lpszMenuName = nullptr;
window_class.lpszClassName = window_class_name;
window_class.hIconSm = nullptr;
if (!RegisterClassExW(&window_class))
{
return 1;
}
HWND window = CreateWindowExW(0, window_class_name, L"Example window", window_style, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, nullptr, nullptr, instance, nullptr);
if (!window)
{
return 1;
}
UINT dpi = GetDpiForWindow(window);
float scaling_factor = static_cast<float>(dpi) / 96;
// Actually set the appropriate window size
RECT scale;
scale.left = 0;
scale.top = 0;
scale.right = static_cast<LONG>(300 * scaling_factor);
scale.bottom = static_cast<LONG>(150 * scaling_factor);
if (!AdjustWindowRectExForDpi(&scale, window_style, false, 0, dpi))
{
return 1;
}
if (!SetWindowPos(window, nullptr, 0, 0, scale.right - scale.left, scale.bottom - scale.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE))
{
return 1;
}
ShowWindow(window, SW_SHOWNORMAL);
// Message loop
MSG message;
int result;
while ((result = GetMessageW(&message, nullptr, 0, 0)) != 0)
{
if (result == -1)
{
return 1;
}
else
{
TranslateMessage(&message);
DispatchMessageW(&message);
}
}
return static_cast<int>(message.wParam);
}
The windows can move from one screen to the next and recalculate window size successfully.

SetWindowPos centers window when position is adjacent to working area border

I'm trying to place dialog window adjacent to desktop's top or bottom border.
Code:
CRect MonitorWorkingArea(HMONITOR monitor)
{
MONITORINFOEX monInfo;
zeroVar(monInfo);
monInfo.cbSize = sizeof(monInfo);
GetMonitorInfo(monitor, &monInfo);
return monInfo.rcWork;
}
CRect MonitorWorkingArea_Wnd(HWND hwnd)
{
return MonitorWorkingArea(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST));
}
CRect MonitorWorkArea_Wnd(CWnd& wnd)
{
return MonitorWorkingArea_Wnd(wnd.GetSafeHwnd());
}
void CMyDialog::SetDefaultWndPos(bool toBottom)
{
// Here we can be sure, that
// a) parent of this window is not null, is visible, not minimized
// b) this window smaller than working area of desktop
// c) it has WS_POPUP style
CRect rcThis;
GetWindowRect(&rcThis);
// Shift our rectangle to most upper or most bottom position
const CRect rcDesktop = MonitorWorkingArea_Wnd(*this);
rcThis.MoveToY(toBottom ? rcDesktop.bottom - rcThis.Height() : 0);
// Move window
SetWindowPos(NULL, rcThis.left, rcThis.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
Real code is bit more complex, I omit some checks and features for simplicity.
I have two monitors, both are 1920×1080 and in virtual coordinate space they are laying on:
Primary: (0,0) — (1920,1080)
Secondary: (1920,0) — (3840, 1080)
Code above works fine when window placed on primary monitor, but on secondary one it's works unexpectedly: it centers window based on it's parent.
For instance I'm calling SetDefaultWndPos(false) and rcThis being calculated as {left:2710, top:0, right:3423, bottom:550}. So SetWindowPos is called with zero y:
SetWindowPos(NULL, 2710, 0, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
But in handler of WM_WINDOWPOSCHANGING
void CMyDialog::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
__super::OnWindowPosChanging(lpwndpos);
}
I see in debug x = 2710 (unchanged) and y = 475 (unexpected). Next I check dialog's y-position in Spy utility, it's 475. Dialog window looks like it was centered on it's parent window.
All it looks like an OS errorneously detected requested window position as out-of-desktop and used some default positioning.
Only workarund I found is to decrease desktop working area on 1 pixel from each side:
CRect MonitorWorkingArea(HMONITOR monitor)
{
MONITORINFOEX monInfo;
zeroVar(monInfo);
monInfo.cbSize = sizeof(monInfo);
GetMonitorInfo(monitor, &monInfo);
CRect rc = monInfo.rcWork;
if( !(monInfo.dwFlags & MONITORINFOF_PRIMARY) )
{
++rc.left;
++rc.top;
--rc.right;
--rc.bottom;
}
return rc;
}
It works but looks as strange ugly hack.
Can anybody explain what happens here and help me with good decision?
Can it be OS version dependent? (I use Windows 7 Professional SP1).

OpenGL Viewport On Drag Update (Winapi)

In my current project I am working on I would like to make the opengl viewport window resize from when the user resizes the drag window ("SizeBox"), I planned on using the windows "ENTERSIZEMOVE" function from the windows.h window api to get the signal to redraw the viewport.I would then call "UpdateRender" to update my viewport.
On running my program I only seem to get one update call to resize the window (even if I stop and start dragging again),I also have a cube in the scene which is rotating it is entered (0.0f,0.0f,10.of). I wanted the cube to move along with the window "resizing" instead of it getting covered over by the window,Since the cube is set to the centre of the viewport so if I am correct I should not need to move it via a gltransform.
If anyone has any thoughts on why I am not getting a constant viewport "refresh" from the window being dragged it would be much appreciated.
Message loop handler (snippet)
{ case WM_ENTERSIZEMOVE:
render->UpdateRender();
break;
}
Update Render
void Render::UpdateRender()
{
int update_x = rect.right - rect.left;
int update_y = rect.bottom - rect.top;
glViewport(0,0 ,update_y/2,update_x/2);
}
Create Window
int window::Wincreate(HINSTANCE hInstance, char *winname, int winwidth, int winheight)
{
Hwnd = CreateWindow("Game Engine", winname, WS_VISIBLE | WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE, 0, 0, winwidth , winheight , 0, 0, hInstance, 0);
if (!Hwnd)
{
MessageBox(0, "Error: Could not Create Window", "Error", MB_OK);
}
Engine->EnableOGLAPI();
Draw->Initalize();
return 0;
}
Main application Loop
int window::Winloop(MSG msg)
{
while (running)
{
if (PeekMessage(&msg,0,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
angle++;
Draw->MainRender();
SwapBuffers(hDC);
}
}
return 0;
}

Unresolved externals in c++ code using OpenGL [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
Here's my (O.K. not my :)) code:
/*
* This Code Was Created By Jeff Molofee 2000
* A HUGE Thanks To Fredric Echols For Cleaning Up
* And Optimizing This Code, Making It More Flexible!
* If You've Found This Code Useful, Please Let Me Know.
* Visit My Site At nehe.gamedev.net
*/
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\GLaux.h> // Header File For The Glaux Library
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
return TRUE; // Everything Went OK
}
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,TEXT("Release Of DC And RC Failed."),TEXT("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL,TEXT("Release Rendering Context Failed."),TEXT("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Set RC To NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
{
MessageBox(NULL,TEXT("Release Device Context Failed."),TEXT("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,TEXT("Could Not Release hWnd."),TEXT("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}
if (!UnregisterClass(TEXT("OpenGL"),hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL,TEXT("Could Not Unregister Class."),TEXT("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
}
/* This Code Creates Our OpenGL Window. Parameters Are: *
* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = TEXT("OpenGL"); // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,TEXT("Failed To Register The Window Class."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (fullscreen) // Attempt Fullscreen Mode?
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox(NULL,TEXT("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),TEXT("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,TEXT("Program Will Now Close."),TEXT("ERROR"),MB_OK|MB_ICONSTOP);
return FALSE; // Return FALSE
}
}
}
if (fullscreen) // Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
// Create The Window
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
TEXT("OpenGL"), // Class Name
TEXT("title"), // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Window Creation Error."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Can't Create A GL Device Context."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Can't Find A Suitable PixelFormat."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Can't Set The PixelFormat."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Can't Create A GL Rendering Context."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Can't Activate The GL Rendering Context."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,TEXT("Initialization Failed."),TEXT("ERROR"),MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active=TRUE; // Program Is Active
}
else
{
active=FALSE; // Program Is No Longer Active
}
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is A Key Being Held Down?
{
keys[wParam] = TRUE; // If So, Mark It As TRUE
return 0; // Jump Back
}
case WM_KEYUP: // Has A Key Been Released?
{
keys[wParam] = FALSE; // If So, Mark It As FALSE
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain( HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
MSG msg; // Windows Message Structure
BOOL done=FALSE; // Bool Variable To Exit Loop
// Ask The User Which Screen Mode They Prefer
if (MessageBox(NULL,TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start FullScreen?"),MB_YESNO|MB_ICONQUESTION)==IDNO)
{
fullscreen=FALSE; // Windowed Mode
}
// Create Our OpenGL Window
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
while(!done) // Loop That Runs While done=FALSE
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message==WM_QUIT) // Have We Received A Quit Message?
{
done=TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
if (keys[VK_ESCAPE]) // Was ESC Pressed?
{
done=TRUE; // ESC Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
}
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1]=FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
}
}
// Shutdown
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
How I can solve problem with unresolved externals?
I can't post image so here's link to image with some errors what my VC++ Express wrote: http://i.stack.imgur.com/2v2US.png
Unresolved externals usually means you did not input the correct libraries. In your project settings, what OpenGL libraries did you include? Standard is
opengl32.lib
glu32.lib
in your project linker settings.