Я пытаюсь использовать преимущества SFML (я все еще новичок здесь) в проекте C++ windows forms (также новый здесь: D). Моя идея, когда событие появляется в этом окне SFML, чтобы отобразить изображение. Мне удалось заставить окно SFML всплывать, когда событие происходит, но оно появляется только с пустым экраном, но не показывает текстуру, которую я хочу ... Вот выдержки с кодом, в котором участвует SFML, с «//. .»Я буду вырезать ненужный код:Я получаю только черный экран в SFML sf :: RenderWindow
BatteryAlarmDlg.h
class CBatteryAlarmDlg : public CDialog
{
// ...
protected:
// ...
// timers
Timer m_tPowerCheck; // the struct Timer has just two members - int id and int duration
Timer m_tWindowRefresh;
// sounds
sf::SoundBuffer m_sfsbWarningMessageBuffer;
sf::Sound m_sfsWarningMessageSound;
std::string m_sPathToWarningMessageSoundFile;
// sfml window management support
sf::RenderWindow m_sfwChangePowerMessage;
sf::Texture m_sftChangePowerMessage;
sf::RectangleShape m_sfrChangePowerMessage;
bool m_bIsWindowAlive;
sf::Event m_sfeEvent;
// ...
};
на код выше, я просто объявить членов.
BatteryAlarmDlg.cpp
// ...
BOOL CBatteryAlarmDlg::OnInitDialog()
{
// ...
/// init timers ///
m_tPowerCheck = Timer(42, 1000); // a timer with id == 42 and with a duration == 1,000 ms
SetTimer(m_tPowerCheck.id, m_tPowerCheck.duration, nullptr);
m_tWindowRefresh = Timer(1, 15);
SetTimer(m_tWindowRefresh.id, m_tWindowRefresh.duration, nullptr);
/// init sounds ///
m_sPathToWarningMessageSoundFile = "warning-message-2.wav";
if (!m_sfsbWarningMessageBuffer.loadFromFile(m_sPathToWarningMessageSoundFile))
{
MessageBox("Error loading of warning message sound file!");
}
m_sfsWarningMessageSound.setBuffer(m_sfsbWarningMessageBuffer);
/// init messages windows ///
m_sfwChangePowerMessage.setFramerateLimit(60);
if (!m_sftChangePowerMessage.loadFromFile("ChagePowerMessage.png"))
{
MessageBox("Error loading of warning message image file!");
}
m_sfrChangePowerMessage.setSize
(
sf::Vector2f(m_sfwChangePowerMessage.getSize().x, m_sfwChangePowerMessage.getSize().y)
);
m_sfrChangePowerMessage.setPosition(0, 0);
m_sfrChangePowerMessage.setTexture(&m_sftChangePowerMessage);
m_bIsWindowAlive = false;
return TRUE; // return TRUE unless you set the focus to a control
}
// ...
void CBatteryAlarmDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == m_tPowerCheck.id)
{
if (GetSystemPowerStatus(&m_spsPower) == 0)
{
// message = "Error: Could not get the system power status!";
MessageBox("Error: Could not get the system power status!");
}
if (m_spsPower.ACLineStatus == 0 & m_iPowerChange == 1)
{
if (!m_sfwChangePowerMessage.isOpen())
{
m_sfwChangePowerMessage.create(sf::VideoMode(800, 600), "Battery allarm : System Power Changed!");
}
m_sfwChangePowerMessage.clear();
m_sfwChangePowerMessage.draw(m_sfrChangePowerMessage);
m_sfwChangePowerMessage.display();
m_iPowerChange = 0;
m_sfsWarningMessageSound.play();
m_bIsWindowAlive = true;
}
if (m_spsPower.ACLineStatus == 1 & m_iPowerChange == 0)
{
m_iPowerChange = 1;
}
}
if (nIDEvent = m_tWindowRefresh.id)
{
if (m_bIsWindowAlive)
{
while (m_sfwChangePowerMessage.pollEvent(m_sfeEvent))
{
if
(
m_sfeEvent.type == sf::Event::Closed ||
(m_sfeEvent.type == sf::Event::KeyPressed && m_sfeEvent.key.code == sf::Keyboard::Escape)
)
{
m_bIsWindowAlive = false;
}
}
m_sfwChangePowerMessage.clear();
m_sfwChangePowerMessage.draw(m_sfrChangePowerMessage);
m_sfwChangePowerMessage.display();
}
if(!m_bIsWindowAlive && m_sfwChangePowerMessage.isOpen())
{
m_sfwChangePowerMessage.close();
}
}
CDialog::OnTimer(nIDEvent);
}
Основная идея, если есть событие и первый таймер (m_tPowerCheck на каждый 1 секунду) запускается из затем показывает окно SFML нанесения изображения, а затем играть звук. На каждые 15 миллисекунд (m_tWindowRefresh) проверьте, открыто ли окно sfml и перерисовывает изображение - здесь я не уверен, что это необходимо, потому что это неподвижное изображение, но изначально я думал, что черный экран - это потому, что я не обновляю это постоянно. Но все же - только черный экран ...: \
Редактировать: звук из SFML отлично работает.
Первый шаг в отладке программы: [создать mcve] (http://stackoverflow.com/help/mcve). – Hiura
Можете ли вы рассказать мне, что должно делать 'CDialog :: OnTimer (nIDEvent),' call в конце используется, это похоже на инфинитивный вызов рекурсии. Также расскажите нам, как вызываются «BOOL CBatteryAlarmDlg :: OnInitDialog()» и «void CBatteryAlarmDlg :: OnTimer (UINT_PTR nIDEvent)». –
@FotoBlysk, спасибо за ваш вопрос. Как я уже упоминал выше, это проект C++ windows forms. Этот метод генерируется (почти) автоматически - BOOL CBatteryAlarmDlg :: OnInitDialog() - это где обычно переменные инициализируются до появления диалоговых окон Windows. – winsett