Thank you for your answers.
What is your reason to mix WinAPI code with SFML?
I want to use SFML for Joystick Input and Graphics but i need the Window Message Loop to interact with an Serial Port.
No, it should work fine. Calling DispatchMessage will pass the event to all the registered event procedures, which includes both SFML's and user's ones. Unless there's something wrong in user's code.
So please show your full code.
How do i register my procedure? I think that is the problem.
The full Code of main.cpp:
I created an Standard Win32 Project with Visual Studio and added SFML.
#include "stdafx.h"
#include "AVR_Remote.h"
#include <SFML/Graphics.hpp>
#define MAX_LOADSTRING 100
// Globale Variablen:
HINSTANCE hInst; // Aktuelle Instanz
TCHAR szTitle[MAX_LOADSTRING]; // Titelleistentext
TCHAR szWindowClass[MAX_LOADSTRING]; // Klassenname des Hauptfensters
//Variabeln für SFML
sf::RenderWindow RenderWin;
sf::Image image;
sf::Sprite sBackground;
// Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen:
ATOM MyRegisterClass(HINSTANCE hInstance);
HWND InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
bool InitSFML(HWND hWnd, HINSTANCE hInstance);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Hier Code einfügen.
MSG msg;
HACCEL hAccelTable;
HWND hWnd;
// Globale Zeichenfolgen initialisieren
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_AVR_REMOTE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Anwendungsinitialisierung ausführen:
hWnd = InitInstance(hInstance, nCmdShow);
if(!hWnd)
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AVR_REMOTE));
if(!InitSFML(hWnd, hInstance))
return FALSE;
// Hauptnachrichtenschleife:
do
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
//Process SFML Code
//Process events
sf::Event Event;
while (RenderWin.GetEvent(Event))
{
if(Event.Type == sf::Event::KeyPressed)
{
if(Event.Key.Code == sf::Key::Escape)
{
//Quit
return false;
}
}
}
RenderWin.Clear();
RenderWin.Draw(sBackground);
RenderWin.Display();
}
}while(msg.message != WM_QUIT);
return (int) msg.wParam;
}
//
// FUNKTION: MyRegisterClass()
//
// ZWECK: Registriert die Fensterklasse.
//
// KOMMENTARE:
//
// Sie müssen die Funktion verwenden, wenn Sie möchten, dass der Code
// mit Win32-Systemen kompatibel ist, bevor die RegisterClassEx-Funktion
// zu Windows 95 hinzugefügt wurde. Der Aufruf der Funktion ist wichtig,
// damit die kleinen Symbole, die mit der Anwendung verknüpft sind,
// richtig formatiert werden.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AVR_REMOTE));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_AVR_REMOTE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNKTION: InitInstance(HINSTANCE, int)
//
// ZWECK: Speichert das Instanzenhandle und erstellt das Hauptfenster.
//
// KOMMENTARE:
//
// In dieser Funktion wird das Instanzenhandle in einer globalen Variablen gespeichert, und das
// Hauptprogrammfenster wird erstellt und angezeigt.
//
HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
RECT size;
size.top = 0;
size.bottom = 800;
size.left = 0;
size.right = 1200;
AdjustWindowRect(&size, WS_OVERLAPPEDWINDOW, true);
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, size.right-size.left, size.bottom-size.top, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return hWnd;
}
//
// FUNKTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// ZWECK: Verarbeitet Meldungen vom Hauptfenster.
//
// WM_COMMAND - Verarbeiten des Anwendungsmenüs
// WM_PAINT - Zeichnen des Hauptfensters
// WM_DESTROY - Beenden-Meldung anzeigen und zurückgeben
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Menüauswahl bearbeiten:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Hier den Zeichnungscode hinzufügen.
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Meldungshandler für Infofeld.
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;
}
bool InitSFML(HWND hWnd, HINSTANCE hInstance)
{
// Create an SFML View
HWND View = CreateWindow("STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, 1200, 800, hWnd, NULL, hInstance, NULL);
RenderWin.Create(View, sf::WindowSettings(24,8,4));
// Load Background for the Window
if(!image.LoadFromFile("image1.png"))
return false;
sBackground.SetImage(image);
sBackground.SetPosition(0,0);
return true;
}