'myfunc' : local function definitions are illegal - visual-studio-2010

i have the following code that works well if it is an win32 console application
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
if( !InitBoard() )
{
return 1;
}
HWND hDialog = 0;
hDialog = CreateDialog (hInst,
MAKEINTRESOURCE (IDD_MAIN),
0,
DialogProc);
if (!hDialog)
{
char buf [100];
wsprintf (buf, "Error x%x", GetLastError ());
MessageBox (0, buf, "CreateDialog", MB_ICONEXCLAMATION | MB_OK);
return 1;
}
#if !defined (_WRITE_MPEG_ )
InitBufferHandling();
StartRTPProcess();
// give vlc some time to get started before shoving buffers at it...
#endif
Sleep(250);
if( !StartAcquisition() )
return 1;
g_hWnd = hDialog;
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
BOOL CALLBACK DialogProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
switch (uMessage)
{
case WM_CLOSE:
PostQuitMessage(0);
return FALSE;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
ShutDownAcquisition();
PostQuitMessage(1);
return FALSE;
case IDC_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, About);
return TRUE;
default:
break;
}
default:
return FALSE;
}
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
int SelectBoard()
{
DialogBox(hInst, MAKEINTRESOURCE(IDD_SELECT_BOARD), g_hWnd, SelectBoardProc);
return g_SelectedBoard;
}
BOOL CALLBACK SelectBoardProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
switch (uMessage)
{
case WM_INITDIALOG:
{
int nBoards = GetBoardCount();
SelBoard BoardInfo;
char ButtonCaption[64];
int nButtonHeight = 17;
for( int i = 0; i < nBoards; i++ )
{
GetBoardSelection( i, &BoardInfo );
wsprintf( ButtonCaption, "%s %s %s", BoardInfo.szBoardName, BoardInfo.szSerialNumber,
BoardInfo.bClaimed ? "(Busy)" : " " );
CreateWindowEx( 0, TEXT("BUTTON"), ButtonCaption, WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
7, 7 + i*nButtonHeight, 282, nButtonHeight, hDlg, (HMENU)(BOARD_RADIO_1 + i), hInst, 0 );
}
g_SelectedBoard = 0;
}
return (INT_PTR)TRUE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
switch (LOWORD(wParam))
{
case BOARD_RADIO_1:
case BOARD_RADIO_1 + 1:
case BOARD_RADIO_1 + 2:
case BOARD_RADIO_1 + 3:
case BOARD_RADIO_1 + 4:
case BOARD_RADIO_1 + 5:
g_SelectedBoard = LOWORD(wParam) - BOARD_RADIO_1;
return TRUE;
break;
case IDOK:
EndDialog(hDlg, LOWORD(wParam));
return FALSE;
}
}
}
return FALSE;
}
i want to convert the above code into an window service so when i does:-
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
}
// Service initialization
int InitService()
{
int result;
result = WriteToLog("Monitoring started.");
return(result);
}
void ServiceMain(int argc, char** argv)
{
int error;
MEMORYSTATUS memory;
char buffer[16];
int result;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
"MemoryStatus",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
// Initialize Service
error = InitService();
if (error)
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{void myfunc(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
if( !InitBoard() )
{
return 1;
}
HWND hDialog = 0;
hDialog = CreateDialog (hInst,
MAKEINTRESOURCE (IDD_MAIN),
0,
DialogProc);
if (!hDialog)
{
char buf [100];
wsprintf (buf, "Error x%x", GetLastError ());
MessageBox (0, buf, "CreateDialog", MB_ICONEXCLAMATION | MB_OK);
return 1;
}
#if !defined (_WRITE_MPEG_ )
InitBufferHandling();
StartRTPProcess();
// give vlc some time to get started before shoving buffers at it...
#endif
Sleep(250);
if( !StartAcquisition() )
return 1;
g_hWnd = hDialog;
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//return (int) msg.wParam;
if (eventchecking)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
Sleep(SLEEP_TIME);
}
// return;
}
return;
}
it gives me an error of error C2601: 'myfunc' : local function definitions are illegal

From your second code block:
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{void myfunc(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
You appear to have suffered a significan cut & paste error, pasting the definition of myfunc into the middle of ServiceMain.
Also look at the end of the code as well:
Sleep(SLEEP_TIME);
}
// return;
}
return;
}
That indenting is a sign of something wrong.

Comment out the following lines from the while loop -
void myfunc(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)

Related

Why GetMessage function return -1 when hwnd value passed?

In this code I am drawing line using LineTo function. When I run below code GetMessage function returning -1 value. I am not getting why it is happening. I search At some places it is given that if hwnd is already destroyed then GetMessage function will return -1. When I pass second parameter of GetMessage as NULL My code runs fine. I am using Visual Studio 2010.
#include<Windows.h>
#include<stdio.h>
long int count_paint =0;
LRESULT CALLBACK my_WindowsProc_1(HWND hwnd, UINT msgkdjaks, WPARAM w, LPARAM l)
{
HDC hdc;
PAINTSTRUCT ps;
switch(msgkdjaks)
{
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
MoveToEx(hdc,30,30,NULL);
LineTo(hdc,210,125);
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,msgkdjaks,w,l);
}
int WINAPI WinMain(HINSTANCE hCur, HINSTANCE hPre, LPSTR lpr, int cmd_arg)
{
MSG msg;
HWND hwnd1,hwnd2;
LPCTSTR class_name=L"My_Window_class";
int x=0;
WNDCLASSEX wc1;
wc1.cbSize=sizeof(WNDCLASSEX);
wc1.style=0;
wc1.lpfnWndProc=my_WindowsProc_1;
wc1.cbClsExtra=0;
wc1.cbWndExtra=0;
wc1.hInstance=hCur;
wc1.hIcon=LoadIcon(NULL, IDI_APPLICATION);
wc1.hCursor=LoadCursor(NULL,IDC_ARROW);
wc1.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wc1.lpszMenuName=NULL;
wc1.lpszClassName=class_name;
wc1.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
if(!RegisterClassEx(&wc1))
{
return 10;
}
hwnd1 = CreateWindow(class_name, L"This is my window1",WS_OVERLAPPEDWINDOW,
200,200,300,300,NULL,NULL,hCur,NULL);
if(hwnd1==NULL)
{
return 20;
}
ShowWindow(hwnd1 , cmd_arg);
UpdateWindow(hwnd1);
BOOL bRet;
while((bRet = GetMessage( &msg, hwnd1, 0, 0 )) != 0)
{
if (bRet == -1){
return -20;
}
else{
TranslateMessage(&msg);//
DispatchMessage(&msg);
}
}
return 0;
}

WINAPI- WM_QUIT message not being sent

I have a callback function:
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(msg == WM_DESTROY || msg == WM_CLOSE) {
std::cout << "Close or get DESTROYED!\n";
}
if(g_mApp)
return g_mApp->MsgProc(hwnd, msg, wParam, lParam);
else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
However, "Close or get Destroyed" isn't printed when I click on the X button or press Alt+F4. Infact, I am unable to move the window by the mouse!
Some other functions:
int GLApp::run() {
__int64 prevTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prevTime);
__int64 countsPerSec = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&countsPerSec);
float secondsPerCount = 1.0f / countsPerSec;
MSG msg = {0};
while(msg.message != WM_QUIT) {
if(!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
__int64 curTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&curTime);
float deltaTime = (curTime - prevTime) * secondsPerCount;
update(deltaTime);
render();
calculateFPS(deltaTime);
prevTime = curTime;
}
}
shutdown();
return static_cast<int>(msg.wParam);
}
bool GLApp::initWindow() {
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = m_hAppInstance;
wcex.lpfnWndProc = MainWndProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcex.lpszClassName = "GLAPPWNDCLASS";
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) {
return outErrorMessage("Failed to register GLAPPWNDCLASS");
}
// ADJUST WINDOW RECT FOR REQUESTED CLIENT SIZE
RECT r;
r.left = r.top = 0;
r.right = m_ClientWidth;
r.bottom = m_ClientHeight;
AdjustWindowRect(&r, m_WindowStyle, FALSE);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = GetSystemMetrics(SM_CXSCREEN)/2 - width / 2;
int y = GetSystemMetrics(SM_CYSCREEN)/2 - height / 2;
m_hAppWnd = CreateWindow("GLAPPWNDCLASS", m_AppTitle, m_WindowStyle, x, y, width, height, NULL, NULL, m_hAppInstance, NULL);
if(!m_hAppWnd) return outErrorMessage("Failed to create window from GLAPPWNDCLASS");
ShowWindow(m_hAppWnd, SW_SHOW);
return true;
}
g_mApp is my own object for implementing the window. initWindow() and run() are called only once respectively. The full class if you will:
#include "GLApp.h"
#include <iostream>
namespace {
GLApp* g_mApp = NULL;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(msg == WM_DESTROY || msg == WM_CLOSE) {
std::cout << "Close or get DESTROYED!\n";
}
if(g_mApp)
return g_mApp->MsgProc(hwnd, msg, wParam, lParam);
else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
GLApp::GLApp(void)
{
}
GLApp::GLApp(HINSTANCE hInstance) {
m_hAppInstance = hInstance;
m_hAppWnd = NULL;
m_hDevContext = NULL;
m_hGLRenderContext = NULL;
m_ClientWidth = 800;
m_ClientHeight = 600;
m_AppTitle = "OpenGL Application";
m_WindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX;
m_FPS = 0.0f;
g_mApp = this;
}
GLApp::~GLApp()
{
}
int GLApp::run() {
__int64 prevTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prevTime);
__int64 countsPerSec = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&countsPerSec);
float secondsPerCount = 1.0f / countsPerSec;
MSG msg = {0};
while(msg.message != WM_QUIT) {
if(!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
__int64 curTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&curTime);
float deltaTime = (curTime - prevTime) * secondsPerCount;
update(deltaTime);
render();
calculateFPS(deltaTime);
prevTime = curTime;
}
}
shutdown();
return static_cast<int>(msg.wParam);
}
bool GLApp::init() {
return initWindow() && initGL();
}
bool GLApp::initWindow() {
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = m_hAppInstance;
wcex.lpfnWndProc = MainWndProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcex.lpszClassName = "GLAPPWNDCLASS";
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) {
return outErrorMessage("Failed to register GLAPPWNDCLASS");
}
// ADJUST WINDOW RECT FOR REQUESTED CLIENT SIZE
RECT r;
r.left = r.top = 0;
r.right = m_ClientWidth;
r.bottom = m_ClientHeight;
AdjustWindowRect(&r, m_WindowStyle, FALSE);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = GetSystemMetrics(SM_CXSCREEN)/2 - width / 2;
int y = GetSystemMetrics(SM_CYSCREEN)/2 - height / 2;
m_hAppWnd = CreateWindow("GLAPPWNDCLASS", m_AppTitle, m_WindowStyle, x, y, width, height, NULL, NULL, m_hAppInstance, NULL);
if(!m_hAppWnd) return outErrorMessage("Failed to create window from GLAPPWNDCLASS");
ShowWindow(m_hAppWnd, SW_SHOW);
return true;
}
bool GLApp::initGL() {
// CREATE OUR DEVICE CONTEXT
m_hDevContext = GetDC(m_hAppWnd);
// CREATE PIXEL FORMAT DESCRIPTOR
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
int format = ChoosePixelFormat(m_hDevContext, &pfd);
if(!SetPixelFormat(m_hDevContext, format, &pfd)) {
return outErrorMessage("Failed to set pixel format");
}
// CREATE RENDER CONTEXT
m_hGLRenderContext = wglCreateContext(m_hDevContext);
if(!wglMakeCurrent(m_hDevContext, m_hGLRenderContext)) {
return outErrorMessage("Failed to create and activate render context");
}
// INITIALIZE GLEW
if(glewInit() != GLEW_OK) {
return outErrorMessage("Failed to initialize GLEW");
}
return true;
}
LRESULT GLApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CLOSE: {
DestroyWindow(hwnd);
return 0;
}
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
void GLApp::calculateFPS(float dt) {
}
void GLApp::shutdown() {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hGLRenderContext);
ReleaseDC(m_hAppWnd, m_hDevContext);
}
This is how it is implemented:
#include "GLApp.h"
#include <iostream>
class TestApp : public GLApp {
public:
TestApp(HINSTANCE hInstance);
~TestApp();
// OVERRIDES
bool init() override;
void update(float dt) override;
void render() override;
LRESULT MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) override;
};
TestApp::TestApp(HINSTANCE hInstance) : GLApp(hInstance) {
}
TestApp::~TestApp() {}
bool TestApp::init() {
return GLApp::init();
}
void TestApp::update(float dt) {
}
void TestApp::render() {
}
LRESULT TestApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
default:
return GLApp::MsgProc(hwnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nCmdShow) {
TestApp app(hInstance);
if(!app.init()) {
return 1;
}
return app.run();
}
bool outErrorMessage(const char* message) {
MessageBox(NULL, message, NULL, MB_OK);
return false;
}
!PeekMessage is wrong, if it returns non-zero you got a message you need to handle.

ChangeClipboardChain() fails when called from console CtrlHandler()

I know, this method is outdated, just curious.
When I call ChangeClipboardChain() from atexit handler, it succeeds. When precc Ctrl-C, it fails. I know it, because other clipboard viewers don't receive WM_CHANGECBCHAIN.
This sample program exits when something is copied to clipboard 4 times:
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
static void pWin32Error(const char* fmt, ...);
static int counter=0;
static HWND nextWnd = NULL;
static
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg) {
case WM_CHANGECBCHAIN:
{
HWND wndRemove = (HWND)wParam;
HWND wndNextNext = (HWND)lParam;
printf("WM_CHANGECBCHAIN %p %p\n", (void*)wndRemove, (void*)wndNextNext);
if (nextWnd == wndRemove) {
printf("saving next window %p\n", (void*)wndNextNext);
nextWnd = wndNextNext;
} else if (nextWnd) {
printf("notifying next window %p\n", (void*)nextWnd);
return SendMessage(nextWnd,uMsg,wParam,lParam);
} else {
printf("not notifying next window %p\n", (void*)nextWnd);
}
}
break;
case WM_DRAWCLIPBOARD:
counter++;
if (counter > 4) exit(0);
printf("WM_DRAWCLIPBOARD\n");
if (nextWnd) {
printf("notifying next window %p\n", (void*)nextWnd);
return SendMessage(nextWnd,uMsg,wParam,lParam);
} else {
printf("not notifying next window %p\n", (void*)nextWnd);
}
break;
default:
return DefWindowProc( hwnd,uMsg,wParam,lParam);
}
return 0;
}
static volatile HWND global_hwnd = NULL;
WNDCLASS wndclass = {
0,/* UINT style;*/
WindowProc,/* WNDPROC lpfnWndProc;*/
0,/* int cbClsExtra;*/
0,/* int cbWndExtra;*/
NULL,/* HINSTANCE hInstance;*/
NULL,/* HICON hIcon;*/
NULL,/* HCURSOR hCursor;*/
NULL,/* HBRUSH hbrBackground;*/
NULL,/* LPCWSTR lpszMenuName;*/
_T("myclipmonitor")/* LPCWSTR lpszClassName;*/
};
static void unreg() {
HWND hwnd;
hwnd = (HWND)InterlockedExchangePointer(&global_hwnd, NULL); /* ignore the "cast to greater size" warning */
if (hwnd) {
printf("Removing self from chain: %p <- %p\n", (void*)hwnd, (void*)nextWnd);
if (!ChangeClipboardChain(hwnd, nextWnd) && GetLastError() != 0) {
pWin32Error("ChangeClipboardChain() failed");
}
}
}
static void exitproc() {
fprintf(stderr, "exitproc()\n");
unreg();
}
static
BOOL WINAPI CtrlHandler( DWORD fdwCtrlType )
{
fprintf(stderr, "CtrlHandler()\n");
unreg();
switch ( fdwCtrlType ) {
case CTRL_C_EVENT:
fprintf(stderr, "\n\n Stopping due to Ctrl-C.\n" );
break;
case CTRL_CLOSE_EVENT:
fprintf(stderr, "\n\n Stopping due to closing the window.\n" );
break;
case CTRL_BREAK_EVENT:
fprintf(stderr, "\n\n Stopping due to Ctrl-Break.\n" );
break;
// Pass other signals to the next handler - ret = FALSE
case CTRL_LOGOFF_EVENT:
fprintf(stderr, "\n\n Stopping due to logoff.\n" );
break;
case CTRL_SHUTDOWN_EVENT:
fprintf(stderr, "\n\n Stopping due to system shutdown.\n" );
break;
default:
fprintf(stderr, "\n\n Stopping due to unknown event.\n" );
}
return FALSE;
}
int _tmain(int argc, _TCHAR* argv[])
{
ATOM classatom;
HINSTANCE hinst = GetModuleHandle(NULL);
MSG msg;
wndclass.hInstance = hinst;
classatom = RegisterClass(&wndclass);
if (classatom == 0) {
pWin32Error("RegisterClass() failed");
return -1;
}
global_hwnd = CreateWindowEx(0, (LPCTSTR)classatom, NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL);
if (!global_hwnd) {
pWin32Error("CreateWindowEx() failed");
return -1;
}
printf("hwnd = %p\n", (void*)global_hwnd);
nextWnd = SetClipboardViewer(global_hwnd);
if (!nextWnd && GetLastError() != 0) {
pWin32Error("SetClipboardViewer() failed");
return -1;
}
printf("nextWnd = %p\n", (void*)nextWnd);
atexit(exitproc);
if (0 == SetConsoleCtrlHandler( CtrlHandler, TRUE )) {
pWin32Error("SetConsoleCtrlHandler() failed");
return -1;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
static char *cleanstr(char *s)
{
while(*s) {
switch((int)*s){
case 13:
case 10:
*s=' ';
break;
}
s++;
}
return s;
}
static void __pWin32Error(int level, DWORD eNum, const char* fmt, va_list args)
{
char emsg[1024];
char *pend = emsg + sizeof(emsg);
size_t count = sizeof(emsg);
unsigned u;
do {
u = (unsigned)_vsnprintf(pend - count, count, fmt, args);
if (u >= count) break;
count -= u;
u = (unsigned)_snprintf(pend - count, count, ": ");
if (u >= count) break;
count -= u;
u = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
pend - count, (DWORD)count, NULL );
if (u == 0) {
u = (unsigned)_snprintf(pend - count, count, "0x%08x (%d)", eNum, eNum);
}
} while(0);
emsg[sizeof(emsg)-1] = '\0';
pend = cleanstr(emsg);
if (pend < emsg + sizeof(emsg)-1) {
pend++;
*pend = '\0';
}
pend[-1] = '\n';
puts(emsg);
}
static void pWin32Error(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
__pWin32Error(0, GetLastError(), fmt, args);
va_end(args);
}

OpenGL -> wglCreateContext, wglMakeCurrent in WndProc's WM_CREATE makes rendering fail

OS: Windows 7, 64 bit
Visual Studio 2010, debug, 32 bit
I'm trying out a simple Windows program to start working with openGL: all the program should do is clear the color buffer with glClear(GL_COLOR_BUFFER_BIT).
In the tutorials I found on the web, I find that people are creating and setting the openGL context during the creation of the window (and thus during the treatment of the WM_CREATE message). Somehow, I find that this doesn't work for my code and I don't seem to be able to figure it out. So if anyone could point me in the right direction.
Please find hereafter the code how I expect that it should work based on tutorials:
#include <windows.h>
#include <GL\glew.h>
#include <GL\wglew.h>
#include "Application.h"
HWND ghMainWnd = 0;
bool InitWindowsApp(HINSTANCE instanceHandle, int show);
int Run();
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
HDC hDC;
HGLRC hGLRC;
HPALETTE hPalette;
void SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int pixelFormat = ChoosePixelFormat(hDC, &pfd);
if(pixelFormat == 0)
{
MessageBox(ghMainWnd, L"ChoosePixelFormat() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
if(!SetPixelFormat(hDC, pixelFormat, &pfd))
{
MessageBox(ghMainWnd, L"SetPixelFormat() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
}
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
if(!InitWindowsApp(hInstance, nShowCmd))
return 0;
return Run();
}
bool InitWindowsApp(HINSTANCE instanceHandle, int show)
{
WNDCLASS wc;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = L"BasicWndClass";
if(!RegisterClass(&wc))
{
MessageBox(0, L"RegisterClass failed", 0, 0);
return false;
}
ghMainWnd = CreateWindow(
L"BasicWndClass",
L"BasicWindowsApp",
WS_OVERLAPPEDWINDOW,
0,
0,
600,
600,
0,
0,
instanceHandle,
0);
if(ghMainWnd == 0)
{
MessageBox(0, L"CreateWindow failed", 0, 0);
return false;
}
ShowWindow(ghMainWnd, show);
UpdateWindow(ghMainWnd);
return true;
}
int Run()
{
MSG msg = {0};
Application *pApp = new Application();
pApp->Init();
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//Do Other stuff
pApp->Draw();
SwapBuffers(hDC);
}
}
if(pApp)
{
delete pApp;
pApp = nullptr;
}
return (int)msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
hDC = GetDC(ghMainWnd);
SetupPixelFormat();
hGLRC = wglCreateContext(hDC);
if(!hGLRC)
{
MessageBox(ghMainWnd, L"wglCreateContext() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
if(!wglMakeCurrent(hDC, hGLRC))
{
MessageBox(ghMainWnd, L"wglMakeCurrent() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
glViewport(0, 0, 600, 600);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
return 0;
case WM_LBUTTONDOWN:
return 0;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
DestroyWindow(ghMainWnd);
return 0;
case WM_DESTROY:
if(hGLRC)
{
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(hGLRC);
}
ReleaseDC(ghMainWnd, hDC);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
Below, I found a "hack" to make it work: I basically move the opengl context creation into the InitWindowsApp() function... But why does the code above doesn't work?
#include <windows.h>
#include <GL\glew.h>
#include <GL\wglew.h>
#include "Application.h"
HWND ghMainWnd = 0;
bool InitWindowsApp(HINSTANCE instanceHandle, int show);
int Run();
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
HDC hDC;
HGLRC hGLRC;
HPALETTE hPalette;
void SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int pixelFormat = ChoosePixelFormat(hDC, &pfd);
if(pixelFormat == 0)
{
MessageBox(ghMainWnd, L"ChoosePixelFormat() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
if(!SetPixelFormat(hDC, pixelFormat, &pfd))
{
MessageBox(ghMainWnd, L"SetPixelFormat() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
}
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
if(!InitWindowsApp(hInstance, nShowCmd))
return 0;
return Run();
}
bool InitWindowsApp(HINSTANCE instanceHandle, int show)
{
WNDCLASS wc;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = L"BasicWndClass";
if(!RegisterClass(&wc))
{
MessageBox(0, L"RegisterClass failed", 0, 0);
return false;
}
ghMainWnd = CreateWindow(
L"BasicWndClass",
L"BasicWindowsApp",
WS_OVERLAPPEDWINDOW,
0,
0,
600,
600,
0,
0,
instanceHandle,
0);
if(ghMainWnd == 0)
{
MessageBox(0, L"CreateWindow failed", 0, 0);
return false;
}
ShowWindow(ghMainWnd, show);
UpdateWindow(ghMainWnd);
hDC = GetDC(ghMainWnd);
SetupPixelFormat();
hGLRC = wglCreateContext(hDC);
if(!hGLRC)
{
MessageBox(ghMainWnd, L"wglCreateContext() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
if(!wglMakeCurrent(hDC, hGLRC))
{
MessageBox(ghMainWnd, L"wglMakeCurrent() failed", L"Error", MB_ICONERROR | MB_OK);
exit(1);
}
glViewport(0, 0, 600, 600);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
return true;
}
int Run()
{
MSG msg = {0};
Application *pApp = new Application();
pApp->Init();
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//Do Other stuff
pApp->Draw();
SwapBuffers(hDC);
}
}
if(pApp)
{
delete pApp;
pApp = nullptr;
}
return (int)msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
return 0;
case WM_LBUTTONDOWN:
return 0;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
DestroyWindow(ghMainWnd);
return 0;
case WM_DESTROY:
if(hGLRC)
{
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(hGLRC);
}
ReleaseDC(ghMainWnd, hDC);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
When WM_CREATE arrives, your ghMainWnd is still NULL (the message is sent before the CreateWindow call returns). Instead, use the hWnd parameter of the message in your GetDC call.

Win32: No Window Appears

I was programming the example code from Frank Luna's book "Introduction to 3D Game Programming with DirectX 10". The code is the first Win32 example in the Appendix A: Windows Programming section.
Right now, the program compiles under both VC++ 2008/2010, but no window appears, although the debug session has started and I have to forcefully close it. I have no idea where it is, I'm not using Win32 Console mode, I have closed all other windows and no other IDE or session of VC++ is running.
Any idea why this might be happening?
PS: I have also checked my Processes. It is indeed running.
#include <Windows.h>
HWND ghMainWnd = 0;
bool InitWindowsApp(HINSTANCE instanceHandle, int show);
int Run();
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI
WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd )
{
if( !InitWindowsApp(hInstance, nShowCmd) )
return 0;
return Run();
}
bool InitWindowsApp( HINSTANCE instanceHandle, int show )
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = L"BasicWndClass";
if( !RegisterClass(&wc) )
{
MessageBox(0, L"RegisterClass FAILED", 0, 0);
return false;
}
ghMainWnd = CreateWindow(
L"BasicWndClass",
L"Win32Basic",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
instanceHandle,
0);
if( ghMainWnd = 0 )
{
MessageBox( 0, L"Window Creation FAILED", 0, 0 );
return false;
}
ShowWindow( ghMainWnd, show );
UpdateWindow( ghMainWnd );
return true;
}
int Run()
{
MSG msg = {0};
BOOL bRet = 1;
while( bRet = GetMessage( &msg, 0, 0, 0 ) != 0 )
{
if( bRet == -1 )
{
MessageBox( 0, L"GetMessage FAILED", 0, 0 );
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
LRESULT CALLBACK
WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_LBUTTONDOWN:
MessageBox( 0, L"Hello, World", 0, 0 );
return 0;
case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
DestroyWindow( ghMainWnd );
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
Change this:
if( ghMainWnd = 0 )
{
MessageBox( 0, L"Window Creation FAILED", 0, 0 );
return false;
}
to:
if( ghMainWnd == 0 )
{
MessageBox( 0, L"Window Creation FAILED", 0, 0 );
return false;
}
Two equals signs instead of one. :)
Wild guess: _UNICODE is not defined by project settings. Use CreateWindowW, RegisterClassW, to avoid dependency.

Resources