I'm missing something fundamental, and probably both simple and obvious.
My issue:
I have a view (CPlaybackView, derived from CView).
The view displays a bunch of objects derived from CRectTracker (CMpRectTracker).
These objects each contain a floating point member.
I want to display that floating point member when the mouse hovers over the CMpRectTracker.
The handler method is never executed, although I can trace through OnIntitialUpdate, PreTranslateMessage,
and OnMouseMove.
This is in Visual C++ v. 6.0.
Here's what I've done to try to accomplish this:
1. In the view's header file:
public:
BOOL OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult);
private:
CToolTipCtrl m_ToolTip;
CMpRectTracker *m_pCurrentRectTracker;//Derived from CRectTracker
2. In the view's implementation file:
a. In Message Map:
ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTipNeedText)
b. In CPlaybackView::OnInitialUpdate:
if (m_ToolTip.Create(this, TTS_ALWAYSTIP) && m_ToolTip.AddTool(this))
{
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, SHRT_MAX);
m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, 200);
m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, 200);
}
else
{
TRACE("Error in creating ToolTip");
}
this->EnableToolTips();
c. In CPlaybackView::OnMouseMove:
if (::IsWindow(m_ToolTip.m_hWnd))
{
m_pCurrentRectTracker = NULL;
m_ToolTip.Activate(FALSE);
if(m_rtMilepostRect.HitTest(point) >= 0)
{
POSITION pos = pDoc->m_rtMilepostList.GetHeadPosition();
while(pos)
{
CMpRectTracker tracker = pDoc->m_rtMilepostList.GetNext(pos);
if(tracker.HitTest(point) >= 0)
{
m_pCurrentRectTracker = &tracker;
m_ToolTip.Activate(TRUE);
break;
}
}
}
}
d. In CPlaybackView::PreTranslateMessage:
if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd)
{
switch(pMsg->message)
{
case WM_LBUTTONDOWN:
case WM_MOUSEMOVE:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
m_ToolTip.RelayEvent(pMsg);
break;
}
}
e. Finally, the handler method:
BOOL CPlaybackView::OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
{
BOOL bHandledNotify = FALSE;
CPoint CursorPos;
VERIFY(::GetCursorPos(&CursorPos));
ScreenToClient(&CursorPos);
CRect ClientRect;
GetClientRect(ClientRect);
// Make certain that the cursor is in the client rect, because the
// mainframe also wants these messages to provide tooltips for the
// toolbar.
if (ClientRect.PtInRect(CursorPos))
{
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
CString str;
str.Format("%f", m_pCurrentRectTracker->GetMilepost());
ASSERT(str.GetLength() < sizeof(pTTT->szText));
::strcpy(pTTT->szText, str);
bHandledNotify = TRUE;
}
return bHandledNotify;
}
Got it:
Just to put it to bed, here's the result:
BEGIN_MESSAGE_MAP(CPlaybackView, CThreadView)
ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTipNeedText)
END_MESSAGE_MAP()
void CPlaybackView::OnInitialUpdate()
{
if (m_ToolTip.Create(this, TTS_ALWAYSTIP) && m_ToolTip.AddTool(this))
{
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, 2000);
m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, 1);
m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, 1);
m_ToolTip.Activate(FALSE);
BOOL ena = EnableToolTips(TRUE);
}
else
{
TRACE("Error in creating ToolTip");
}
}
void CPlaybackView::OnMouseMove(UINT nFlags, CPoint point)
{
CPlaybackDoc* pDoc = (CPlaybackDoc*) GetDocument();
if (::IsWindow(m_ToolTip.m_hWnd))
{
CMpRectTracker *pRectTracker = HitTest(point);
if(pRectTracker)
{
m_ToolTip.Activate(TRUE);
}
else
{
m_ToolTip.Activate(FALSE);
}
}
}
BOOL CPlaybackView::OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
{
BOOL bHandledNotify = FALSE;
CPoint CursorPos;
VERIFY(::GetCursorPos(&CursorPos));
ScreenToClient(&CursorPos);
CRect MilepostRect;
m_rtMilepostRect.GetTrueRect(MilepostRect);
// Make certain that the cursor is in the client rect, because the
// mainframe also wants these messages to provide tooltips for the
// toolbar.
if(MilepostRect.PtInRect(CursorPos))
{
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
CMpRectTracker *pRectTracker = HitTest(CursorPos);
if(pRectTracker)
{
CString str;
str.Format("%f", pRectTracker->GetMilepost());
ASSERT(str.GetLength() < sizeof(pTTT->szText));
::strcpy(pTTT->szText, str);
bHandledNotify = TRUE;
}
}
return bHandledNotify;
}
BOOL CPlaybackView::PreTranslateMessage(MSG* pMsg)
{
if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd)
{
switch(pMsg->message)
{
case WM_LBUTTONDOWN:
case WM_MOUSEMOVE:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
m_ToolTip.RelayEvent(pMsg);
break;
}
}
return CView::PreTranslateMessage(pMsg);
}
CMpRectTracker* CPlaybackView::HitTest(CPoint &point)
{
CPlaybackDoc* pDoc = (CPlaybackDoc*) GetDocument();
ASSERT_VALID(pDoc);
CMpRectTracker *pTracker = NULL;
POSITION pos = pDoc->m_rtMilepostList.GetHeadPosition();
while(pos)
{
CMpRectTracker tracker = pDoc->m_rtMilepostList.GetNext(pos);
if(tracker.HitTest(point) >= 0)
{
m_CurrentRectTracker = tracker;
pTracker = &m_CurrentRectTracker;
break;
}
}
return pTracker;
}
Related
I have some constants:
constexpr int MonitorDisplay1 = 100;
constexpr int MonitorDisplay2 = 200;
constexpr int MonitorDisplay3 = 400;
constexpr int MonitorDisplay4 = 500;
constexpr int MonitorDisplay1KeyPad = 101;
constexpr int MonitorDisplay2KeyPad = 201;
constexpr int MonitorDisplay3KeyPad = 401;
constexpr int MonitorDisplay4KeyPad = 501;
I have an OnCreate where I setup the hot keys:
int CCenterCursorOnScreenDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (__super::OnCreate(lpCreateStruct) == -1)
return -1;
auto RegisterAppHotkey = [hAppWnd = GetSafeHwnd()](const int nHotKeyID, UINT vk)->bool
{
if (!::RegisterHotKey(hAppWnd, nHotKeyID, MOD_CONTROL | MOD_SHIFT, vk))
{
auto const ec = ::GetLastError();
auto const err_msg = std::format(L"RegisterHotKey failed (error: {})\n",
ec);
AfxMessageBox(err_msg.c_str());
return false;
}
return true;
};
if (m_monitors.rcMonitors.size() > 0)
{
if (!RegisterAppHotkey(MonitorDisplay1, '1'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay1KeyPad, VK_NUMPAD1))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 1)
{
if (!RegisterAppHotkey(MonitorDisplay2, '2'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay2KeyPad, VK_NUMPAD2))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 2)
{
if (!RegisterAppHotkey(MonitorDisplay3, '3'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay3KeyPad, VK_NUMPAD3))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 3)
{
if (!RegisterAppHotkey(MonitorDisplay4, '4'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay4KeyPad, VK_NUMPAD4))
{
return -1;
}
}
return 0;
}
Previously I just had the 4 hotkeys for 1 / 2 / 3 and 4. They still work. I tried to add new hotkeys for for the number pad on the keyboard, but they are not working.
My OnHotKey handler:
void CCenterCursorOnScreenDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
if (nHotKeyId == MonitorDisplay1 || nHotKeyId == MonitorDisplay1KeyPad)
{
CenterCursorOnMonitor(0);
}
else if (nHotKeyId == MonitorDisplay2 || nHotKeyId == MonitorDisplay2KeyPad)
{
CenterCursorOnMonitor(1);
}
else if (nHotKeyId == MonitorDisplay3 || nHotKeyId == MonitorDisplay3KeyPad)
{
CenterCursorOnMonitor(2);
}
else if (nHotKeyId == MonitorDisplay4 || nHotKeyId == MonitorDisplay4KeyPad)
{
CenterCursorOnMonitor(3);
}
__super::OnHotKey(nHotKeyId, nKey1, nKey2);
}
But the number pad versions are not working. Why?
I am unregistering all 8 hotkeys, and num-lock is on. I get no warnings when registering.
This article explains List of Keys (Keyboard, Mouse and Joystick):
Because I was using CTRL + SHIFT, then the meaning of the 4 numeric keys was changing:
End
Down
Page Down
Left
It made sense to change my hotkeys to CTRL + ALT instead to avoid this issue.
Hello I am developing a game on my spare time with AIDE and libGDX. Though AIDE has some missing methods of the libGDX API and I had to create some workarounds to compensate for the missing methods.
So my problem is that with every instance of a collision the app becomes more and more laggy. No new textures are being drawn and non go away. Just a poor implementation that is meant to push you out of said collision tile. It runs fine until you have a few collisions. My thought is that it creates a new variable with every collision and stores it into memory causing a leak. But I can't really tell if that is the case. Oh I'd like to add that I don't have access to a computer, just my phone. Here is my movement class
move.java
public class move
{
float posX;
float posY;
float touchedOnScreenX;
float touchedOnScreenY;
float centerOfScreenX;
float centerOfScreenY;
float posXSetter;
float posYSetter;
float Speed = 150;
float mapBoundsWidth;
float mapBoundsHeight;
boolean upperBounds;
boolean lowerBounds;
boolean rightBounds;
boolean leftBounds;
boolean tileCollition;
public move() {
}
public void renderMove(float delta) {
if(Gdx.input.isTouched()) {
screenAndTouchInfo();
checkBoundsBoolean();
checkForCollision();
}
}
//slows game down
private void checkForCollision()
{
if (upperBounds == false)
{
if (lowerBounds == false)
{
if (rightBounds == false)
{
if (leftBounds == false)
{
if (tileCollition == false)
{
movement();
}
else
{
collitionSide();
}
}
else
{
posX++;
}
}
else
{
posX--;
}
}
else
{
posY++;
}
}
else
{
posY --;
}
}
private void movement()
{
posYSetter = posY;
posXSetter = posX;
if (touchedOnScreenX < centerOfScreenX)
{
posX -= Gdx.graphics.getDeltaTime() * Speed;
}
else
{
posX += Gdx.graphics.getDeltaTime() * Speed;
}
if (touchedOnScreenY < centerOfScreenY)
{
posY -= Gdx.graphics.getDeltaTime() * Speed;
}
else
{
posY += Gdx.graphics.getDeltaTime() * Speed;
}
if (touchedOnScreenY < centerOfScreenY + 64 && touchedOnScreenY > centerOfScreenY - 64)
{
posY = posYSetter;
}
if (touchedOnScreenX < centerOfScreenX + 64 && touchedOnScreenX > centerOfScreenX - 64)
{
posX = posXSetter;
}
}
//buggy and slows game down. Can push you into tile if input is the opposite of the side
public void collitionSide() {
if (tileCollition == true){
if (touchedOnScreenX < centerOfScreenX)
{
posX = posX +10;
}
else
{
posX = posX - 10;
}
if (touchedOnScreenY < centerOfScreenY)
{
posY = posY +10;
}
else
{
posY = posY -10;
}
}
}
private void screenAndTouchInfo()
{
touchedOnScreenX = Gdx.input.getX();
touchedOnScreenY = (Gdx.graphics.getHeight() - Gdx.input.getY());
centerOfScreenX = Gdx.graphics.getWidth() / 2;
centerOfScreenY = Gdx.graphics.getHeight() / 2;
}
//slows game down
private void checkBoundsBoolean()
{
if (posX > mapBoundsWidth)
{
rightBounds = true;
}
else {
rightBounds = false;
}
if (posY > mapBoundsHeight)
{
upperBounds = true;
}
else {
upperBounds = false;
}
if (posX < mapBoundsWidth - mapBoundsWidth)
{
leftBounds = true;
}
else {
leftBounds = false;
}
if (posY < mapBoundsHeight - mapBoundsHeight)
{
lowerBounds = true;
}
else {
lowerBounds = false;
}
}
public void setTileCollision(boolean tileCollision) {
this.tileCollition = tileCollision;
}
public float getPosX() {
return posX;
}
public float getPosY() {
return posY;
}
public float getTouchedOnScreenX() {
return touchedOnScreenX;
}
public float getTouchedOnScreenY() {
return touchedOnScreenY;
}
public float getCenterOfScreenX() {
return centerOfScreenX;
}
public float getCenterOfScreenY() {
return centerOfScreenY;
}
public void setMapboundsWidth(float width) {
this.mapBoundsWidth = width;
}
public void setMapboundsHeight(float height) {
this.mapBoundsHeight = height;
}
}
I know that is a lot of code to comb through and I am sorry if it isn't always clear what is going on. I refactored it to where it would be a little easier to understand. Oh if anyone could tell me why AIDE is missing some methods of libGDX that would be nice too.The most notable one would be Cell.setTile(). That I know is in libGDX's API and can be found in their documentation. But when I implement it it throws a unknown method of class Cell error. I have researched on how to use the method as well with no avail. Had to create int[][] map and a for loop to draw map with another Texture[]. It works. Lol. Thank you to whomever even took the time to look at my long winded double question. Hopefully someone can tell me why this lag is created from said collisions.
I recommend moving your collision code into a separate thread. This should improve performance significantly:
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
#Override
public void run() {
// Physics loop goes here
}
});
Make sure to shutdown the executor when disposing your screen.
The MFC Feature Pack toolbar combo-button (class CMFCToolBarComboBoxButton) works perfectly in horizontal toolbar mode. But in vertical layout mode it is the simple press button without combobox feature.
How to make CMFCToolBarComboBoxButton able to works in vertical mode?
This my solution. I overwrote the behavior of the buttons in vertical mode. And now the button shows combobox drop down window when it is pressed in vertical mode.
You should use class CVerticalableToolBarComboBoxButton instead of CMFCToolBarComboBoxButton in ReplaceButton() method when you add combobox button to your toolbar.
Example: In the images below you can see the behavior of the buttons in the horizontal and vertical modes.
Horizontal mode
Vertical mode
Class code:
class CVerticalableToolBarComboBoxButton
: public CMFCToolBarComboBoxButton
{
DECLARE_SERIAL(CVerticalableToolBarComboBoxButton)
public:
typedef CMFCToolBarComboBoxButton TBase;
protected:
bool m_bDoVerticalMode;
public:
CVerticalableToolBarComboBoxButton(bool bDoVerticalMode = true);
CVerticalableToolBarComboBoxButton(UINT uiID, int iImage, DWORD dwStyle = CBS_DROPDOWNLIST, int iWidth = 0, bool bDoVerticalMode = true);
virtual ~CVerticalableToolBarComboBoxButton();
virtual void Serialize(CArchive& ar);
virtual BOOL OnClick(CWnd* pWnd, BOOL bDelay = TRUE);
virtual void OnChangeParentWnd(CWnd* pWndParent);
virtual void OnMove();
virtual void OnSize(int iSize);
protected:
void AdjustVerticalRect();
};
/////////////////////////////////////////////////////////////////////////////
// CVerticalableToolBarComboBoxButton
IMPLEMENT_SERIAL(CVerticalableToolBarComboBoxButton, CVerticalableToolBarComboBoxButton::TBase, VERSIONABLE_SCHEMA | 1)
CVerticalableToolBarComboBoxButton::CVerticalableToolBarComboBoxButton(bool bDoVerticalMode /*= true*/)
: m_bDoVerticalMode(bDoVerticalMode)
{}
CVerticalableToolBarComboBoxButton::CVerticalableToolBarComboBoxButton(UINT uiID, int iImage, DWORD dwStyle /*= CBS_DROPDOWNLIST*/, int iWidth /*= 0*/, bool bDoVerticalMode /*= true*/)
: TBase(uiID, iImage, dwStyle, iWidth)
, m_bDoVerticalMode(bDoVerticalMode)
{}
CVerticalableToolBarComboBoxButton::~CVerticalableToolBarComboBoxButton()
{}
void CVerticalableToolBarComboBoxButton::Serialize(CArchive& ar)
{
TBase::Serialize(ar);
if (ar.IsLoading()) {
ar >> m_bDoVerticalMode;
}
else {
ar << m_bDoVerticalMode;
}
}
BOOL CVerticalableToolBarComboBoxButton::OnClick(CWnd* pWnd, BOOL bDelay /*= TRUE*/)
{
BOOL bRes = FALSE;
bool bDefault = m_bHorz || !m_bDoVerticalMode;
if (!bDefault) {
if (IsFlatMode()) {
if (m_pWndEdit == NULL) {
m_pWndCombo->SetFocus();
}
else {
m_pWndEdit->SetFocus();
}
m_pWndCombo->ShowDropDown();
if (pWnd != NULL) {
pWnd->InvalidateRect(m_rectCombo);
}
bRes = TRUE;
}
}
if (bDefault) {
bRes = TBase::OnClick(pWnd, bDelay);
}
return bRes;
}
void CVerticalableToolBarComboBoxButton::OnChangeParentWnd(CWnd* pWndParent)
{
TBase::OnChangeParentWnd(pWndParent);
if (!m_bHorz & m_bDoVerticalMode) {
AdjustVerticalRect();
}
}
void CVerticalableToolBarComboBoxButton::OnMove()
{
TBase::OnMove();
if (!m_bHorz & m_bDoVerticalMode) {
AdjustVerticalRect();
}
}
void CVerticalableToolBarComboBoxButton::OnSize(int iSize)
{
TBase::OnSize(iSize);
if (!m_bHorz & m_bDoVerticalMode) {
AdjustVerticalRect();
}
}
void CVerticalableToolBarComboBoxButton::AdjustVerticalRect()
{
ASSERT(m_bDoVerticalMode);
ASSERT(!m_bHorz);
if (m_pWndCombo->GetSafeHwnd() == NULL || m_rect.IsRectEmpty()) {
m_rectCombo.SetRectEmpty();
m_rectButton.SetRectEmpty();
return;
}
CMFCToolBar* pParentBar = nullptr;
{
CWnd* pNextBar = m_pWndCombo->GetParent();
while (pParentBar == nullptr && pNextBar != nullptr) {
pParentBar = DYNAMIC_DOWNCAST(CMFCToolBar, pNextBar);
pNextBar = pNextBar->GetParent();
}
}
if (IsCenterVert() && (!m_bTextBelow || m_strText.IsEmpty()) && (pParentBar != nullptr))
{
const int nRowHeight = pParentBar->GetRowHeight();
const int yOffset = std::max<>(0, (nRowHeight - m_rect.Height()) / 2);
m_rect.OffsetRect(0, yOffset);
}
{
CRect rect;
m_pWndCombo->GetWindowRect(&rect);
const int nWidth = std::max<>(rect.Width(), m_iWidth);
rect.left = m_rect.left;
rect.top = m_rect.top;
rect.right = m_rect.left + nWidth;
rect.bottom = m_rect.top + m_nDropDownHeight;
if ((pParentBar != nullptr) && pParentBar->IsDocked()) {
const UINT nID = pParentBar->GetParentDockSite()->GetDockSiteID();
if (nID == AFX_IDW_DOCKBAR_RIGHT) {
rect.left = m_rect.right - nWidth;
rect.right = m_rect.right;
}
}
m_pWndCombo->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
m_pWndCombo->SetEditSel(-1, 0);
}
{
m_pWndCombo->GetWindowRect(&m_rectCombo);
m_pWndCombo->ScreenToClient(&m_rectCombo);
m_pWndCombo->MapWindowPoints(m_pWndCombo->GetParent(), &m_rectCombo);
}
if (m_bFlat) {
m_rectButton = m_rectCombo;
}
else {
m_rectButton.SetRectEmpty();
}
}
// CVerticalableToolBarComboBoxButton
/////////////////////////////////////////////////////////////////////////////
So I've been picking apart a friend's pong game in order to figure out keyPressed functions, and use them in my balloon game that I mentioned in another post. I believe I've put the code together correctly, keeping procedure and the logical order of things in mind, but for some reason the unexpected token:void keeps coming up as an error message. I've closed off all brackets, and declared all of the global variables to the best of my knowledge, but I keep running into this message.
Here's the code:
int level;
int paddleWidth = 200;
int paddleHeight = 200;
int paddleSpeed = 5;
int posX;
int posY;
boolean p1UP = false;
boolean p1DOWN = false;
boolean p1LEFT = false;
boolean p1RIGHT = false;
void setup() {
size (800,800);
frameRate(60);
smooth();
posX = width/2;
posY = height/2;
}
void draw() {
if (level==0) {
background(0);
textSize(50);
text("PREPARE YOUR ANUS", width/2, height/2-200);
text("PRESS A KEY YOU DINGUS", width/2, height/2-400);
if (keyPressed) level=1;
}
if (level==1) {
background(0);
fill(posX,0,posY);
rect(posX, posY, paddeWidth, paddleHeight);
if(p1UP==true) {
posY -=paddleSpeed;
}
if(p1DOWN==true) {
posY +=paddleSpeed;
}
if(p1LEFT==true) {
posX -= paddleSpeed;
}
if(p1RIGHT==true) {
posX += paddleSpeed;
}
void keyPressed() {
if (key=='w' || key=='W') {
p1UP = true;
}
if (key=='s' || key=='S') {
p1DOWN = true;
}
if (key=='a' || key=='A') {
p1LEFT = true;
}
if (key=='d' || key=='D') {
p1RIGHT = true;
}
}
void keyReleased() {
if (key=='w' || key=='W') {
p1UP = false;
}
if (key=='s' || key=='S') {
p1DOWN = false;
}
if (key=='a' || key=='A') {
p1LEFT = false;
}
if (key=='d' || key=='D') {
p1RIGHT = false;
}
}
}
}
Please use proper formatting. Your indentation made this really hard to read, which is probably why you didn't get an answer right away.
The code with proper formatting looks like this:
boolean p1UP = false;
boolean p1DOWN = false;
boolean p1LEFT = false;
boolean p1RIGHT = false;
void setup() {
size (800,800);
frameRate(60);
smooth();
posX = width/2;
posY = height/2;
}
void draw() {
if (level==0) {
background(0);
textSize(50);
text("use more mature examples", width/2, height/2-200);
text("PRESS A KEY please", width/2, height/2-400);
if (keyPressed) level=1;
}
if (level==1) {
background(0);
fill(posX,0,posY);
rect(posX, posY, paddeWidth, paddleHeight);
if(p1UP==true) {
posY -=paddleSpeed;
}
if(p1DOWN==true) {
posY +=paddleSpeed;
}
if(p1LEFT==true) {
posX -= paddleSpeed;
}
if(p1RIGHT==true) {
posX += paddleSpeed;
}
void keyPressed() {
if (key=='w' || key=='W') {
p1UP = true;
}
if (key=='s' || key=='S') {
p1DOWN = true;
}
if (key=='a' || key=='A') {
p1LEFT = true;
}
if (key=='d' || key=='D') {
p1RIGHT = true;
}
}
void keyReleased() {
if (key=='w' || key=='W') {
p1UP = false;
}
if (key=='s' || key=='S') {
p1DOWN = false;
}
if (key=='a' || key=='A') {
p1LEFT = false;
}
if (key=='d' || key=='D') {
p1RIGHT = false;
}
}
}
}
This makes it obvious that your keyPressed() and keyReleased() functions are inside your draw() function, which isn't valid.
Also note that this line is pretty egregious:
if (keyPressed) level=1;
Even though it's not causing anything bad now, if down the road you want to do more than just set the level equal to 1, you're more likely to introduce logical errors. For that reason, if statements should always be followed by curly brackets, even if they're only one statement:
if (keyPressed){
level=1;
}
I have ClistView control in my MFC application. I need to color some of the items according to its content. For example, if it begins with "No Response to", i need to make it red.
So far, i've tried
BEGIN_MESSAGE_MAP(CMessageView, CListView)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW,customDraw)
END_MESSAGE_MAP()
void CMessageView::Update()
{
CListCtrl& refCtrl = GetListCtrl();
refCtrl.InsertItem(LVIF_TEXT|LVIF_PARAM,0,CTime::GetCurrentTime().Format("%H:%M:%S"),0,0,0,42);
refCtrl.SetItemText(0,1,"some text");
refCtrl.SetItemText(0,2,"No response to open");
}
void CMessageView::customDraw(NMHDR * pNMHDR, LRESULT * pResult)
{
_ASSERTE(*pResult == 0);
NMLVCUSTOMDRAW * pnmlvcd = (NMLVCUSTOMDRAW *)pNMHDR;
DWORD dwDrawStage = pnmlvcd->nmcd.dwDrawStage;
BOOL bSubItem = dwDrawStage & CDDS_SUBITEM;
dwDrawStage &= ~CDDS_SUBITEM;
switch (dwDrawStage)
{
case CDDS_PREPAINT:
{
*pResult = CDRF_NOTIFYITEMDRAW;
break;
}
case CDDS_ITEMPREPAINT:
case CDDS_SUBITEM:
{
if(pnmlvcd->nmcd.lItemlParam == 42)
{
pnmlvcd->clrText = RGB(255,0,0);
}
*pResult = 0;
break;
}
default:
{
*pResult = 0;
break;
}
}
}
But it does not work. The color does not change. Am i missing something or doing something wrong?
If you have VS2008 SP1, it's much easier to use CMFCListCtrl instead - it has virtual functions you can override to set the foreground and background colours of each row.
This code in a simple example application worked for me. My list control has two columns and two items. The second item, second column has item data set to 42, in this case, only that particular subitem had the text changed to red.
void CMFCTestDlg::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
// TODO: Add your control notification handler code here
*pResult = CDRF_DODEFAULT;
switch(pLVCD->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
*pResult = CDRF_NOTIFYSUBITEMDRAW;
break;
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
{
if(1 == pLVCD->iSubItem)
{
if(pLVCD->nmcd.lItemlParam == 42)
{
pLVCD->clrText = RGB(255, 0, 0);
}
}
}
break;
}
}