Something for a child window analogous to `this` - visual-c++

I am a newcomer to programming. I am writing a dialog based application which has a static control on it. Using
Using
void CMy1stDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (this == GetCapture())
{
CClientDC aDC(this);
aDC.SetPixel(point, RGB(255,0,0));
}
}
I can create results like
However what I want is that the locus of mouse is only drawn within the static window. I can't find the reference to this in MSDN and I don't know why the following method fails.
void CMy1stDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pMYSTATIC = GetDlgItem (IDC_MYSTATIC); //IDC_MYSTATIC is the ID of the static control
if (pMYSTATIC == GetCapture())
{
CClientDC aDC(pMYSTATIC);
aDC.SetPixel(point, RGB(255,0,0));
}
}
How can I get what I want? Are there any methods to get something for the static window analogous to this? I will appreciate any help with these.

OK, try this:
void CMy1stDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rect;
// Get static control's rectangle
GetDlgItem(IDC_MYSTATIC)->GetWindowRect(&rect);
// Convert it to client coordinates
ScreenToClient(&rect);
// Check if mouse pointer is inside the static window, if so draw the pixel
if (rect.PtInRect(point))
{
CClientDC dc(this);
dc.SetPixel(point.x, point.y, RGB(255,0,0));
}
}
This code may need some fixes too, eg shrink the rectangle (to its client-only area), before checking whether to draw the pixel.
Please note that you don't need to check GetCapture(); if your dialog hasn't captured the mouse it won't be receiving this message anyway.
Also, all these functions are wrappers of Windows SDK ones, eg the ClientDC() class, basically wraps GetDC()/ReleaseDC().

Related

Can you override the Navigation Controllers 'InteractivePopGestureRecognizer' action?

I'm searching for ways to implement a swipe gesture recognizer which only triggers when you swipe from the outer left side of the screen to the right. We need the gesture to open our custom SideMenu. I tried to use a simple UISwipeGestureRecognizer with the SwipeDirection property set to right, but that gets triggered on every swipe from left to right, no matter what the startpoint of the swipe is.
Ideally, we want the animation of it to look and feel like the InteractivePopGestureRecognizer of a UINavigationController. We are already using a NavigationController, which pushed our MainView over our IntroView. Now, we disable the InteractivePopGestureRecognizer, so you aren't able to go back to the IntroView. That's our problem. If it is possible, we don't want to disable the gesture of the NavigationController, but change the action of it. So the swipe from the far left side of the screen to the right would not pop the current viewcontroller, but open our SideMenu.
Is it possible to override the InteractivePopGestureRecognizer to change the action of it? If this isn't possible, do you have another idea on how to create the exact same gesture recognizer? It has to be possible somehow because many apps only open their SideMenu if your startpoint of the gesture is the left (or right) side of the screen. (e.g. Reddit)
Thanks for any help in advance.
You could use Touch Events and UISwipeGestureRecognizer to do that.
The workaround that is override TouchesBegan method to detect the started point whether fit your needs, and if so add UISwipeGestureRecognizer for View.
SwipeGestureRecognizer rightSwipeGesture;
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
//code here to handle touch
CoreGraphics.CGPoint swipPoint = touch.LocationInView(View);
if(swipPoint.X < 0.5)
{
rightSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Right };
rightSwipeGesture.Swiped += OnSwiped;
View.AddGestureRecognizers(rightSwipeGesture);
}
}
}
public override void TouchesEnded (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
if(null != rightSwipeGesture ){
rightSwipeGesture.Swiped -= OnSwiped;
View.RemoveGestureRecognizers(rightSwipeGesture);
}
}
=============================Update=================================
I found a workaround only use one GestureRecognizer will make it works. You could have a look at UIScreenEdgePanGestureRecognizer. Although it's a Pan gesture, however if you not deal with somethind with the added view, it will work as a swip gesture. In addition, UIScreenEdgePanGestureRecognizer only can work when on the screen edge. You could set the Left edge to handle your needs.
For example:
UIScreenEdgePanGestureRecognizer panRightGestureRecognizer = new UIScreenEdgePanGestureRecognizer();
panRightGestureRecognizer.Edges = UIRectEdge.Left;
panRightGestureRecognizer.AddTarget(() => HandleSwap(panRightGestureRecognizer));
View.AddGestureRecognizer(panRightGestureRecognizer);
private void HandleSwip(UIScreenEdgePanGestureRecognizer panRightGestureRecognizer)
{
Point point = (Point)panRightGestureRecognizer.TranslationInView(View);
if (panRightGestureRecognizer.State == UGestureRecognizerState.Began)
{
Console.WriteLine("Show slider view");
}
}

AndroidPlot PieChart Touch Event

I want to implement a PieChart with a SelectionWidget. Upon clicking on a segment within an AndroidPlot PieChart, I would like the selection widget label text to display info about the current selected segment. There is an example to do this for an XYPlot within the AndroidPlot demo but it does not translate over well to the PieChart. Any help would be appreciated. Thank you.
I just posted a solution to a similar question here. It was necessary to add a new method to the PieRenderer class but there's a link to a build of Androidplot containing the necessary changes. It's not a production build but for whatever it's worth, its at least as stable as the current production version of Androidplot. Once you have the new build, you'll be able to do something like this:
// detect segment clicks:
pie.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
PointF click = new PointF(motionEvent.getX(), motionEvent.getY());
if(pie.getPieWidget().containsPoint(click)) {
Segment segment = pie.getRenderer(PieRenderer.class).getContainingSegment(click);
if(segment != null) {
// handle the segment click...for now, just print
// the clicked segment's title to the console:
System.out.println("Clicked Segment: " + segment.getTitle());
}
}
return false;
}
});
Just replace System.out.println(...) with your code to update the SelectionWidget.

Is it a good idea to use repaint() as a game loop?

class MyCanvas extends Canvas{
protected void paint(Graphics g) {
//Process keyboard
//Update movement/position
//Draw
repaint(); //loop
}
}
Until now I used the Canvas's paint() for the game loop, but I came across some article in the web that says that another thread should be used here
Now I'm wondering if paint() is a good/safe place to process all the data.
So can I continue doing it like this?
Or should I make another thread for that?
I'm not sure of pros and cones of each so I'm not sure which method to choose but I got used to repaint method
I would not use paint() that way, no. paint() should be for painting ... drawing. I would split your monitoring of user input, and game logic processing, outside that method.
Have you considered using the GameCanvas subclass of Canvas?
It gives you some nice double-buffering features. You would create another thread, which would call your GameCanvas' run() method, where it would check for user input, update the game logic, then draw to the off-screen buffer, and finally trigger repainting of the on-screen buffer.
Something like this:
class MyGameCanvas extends GameCanvas implements Runnable {
/** start this game! */
public void start() {
Thread worker = new Thread(this);
worker.start();
}
/** run the game loop */
public void run() {
// Get the Graphics object for the off-screen buffer
Graphics g = getGraphics();
while (true) {
// Check user input and update positions if necessary
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0) {
sprite.move(-1, 0);
}
else if ((keyState & RIGHT_PRESSED) != 0) {
sprite.move(1, 0);
}
// Clear the background to white
g.setColor(0xFFFFFF);
g.fillRect(0,0,getWidth(), getHeight());
// Draw the Sprite
sprite.paint(g);
// Flush the off-screen buffer
flushGraphics();
try {
// TODO: of course, you might want a more intelligent
// sleep interval, that reflects the amount of time
// remaining (if any) in the cycle ...
Thread.sleep(10); //sleep 10 ms
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Note that I put basically everything in the run() method, for brevity. I'm assuming your game is more complicated, and would warrant splitting off separate methods for getting user input, updating logic, and then calling graphics/paint methods. Those would all be called from run().
Usage
Start this in your MIDlet's startApp() method:
MyGameCanvas gameCanvas = new MyGameCanvas();
gameCanvas.start();
exitCommand = new Command("Exit", Command.EXIT, 1);
gameCanvas.addCommand(exitCommand);
gameCanvas.setCommandListener(this);
Display.getDisplay(this).setCurrent(gameCanvas);
References
http://www.codeproject.com/Articles/35833/Programming-2D-Games-in-J2ME
an example that shows a better implementation, if you don't use GameCanvas and just use Canvas.
PowerPoint overview of Game APIs and looping , with code and general theory

Adjust screen elements according to the screen size j2me

I have developed an app in j2me, that is supposed to run over different mobiles like Nokia, Samsung, etc. Supporting .jar files, it runs perfectly but for some of samsung devices the screen expands more than nokia's mobiles, so what I want to do is to get screens properties in a way at start so that I can adjust my texts and images according to that to make it fit for all kind of devices, any idea how can I do it? thanks
If you are worrying about drawing your own text and images, then I guess your app is canvas-based, right? In which case, you can just call your Canvas's getWidth and getHeight methods.
If you are using Canvas you should get your screen properties at sizeChanged method, but be aware that some phones do not call it properly and a simple hack will help:
class MainCanvas extends Canvas {
int lastWidth, lastHeight;
protected void sizeChanged(int w, int h) {
lastWidth = w;
lastHeight = h;
// adjust your user interface to the
// new width and height
// ...
}
protected void paint(Graphics g) {
if (super.getWidth() != lastWidth
|| super.getHeight() != lastHeight) {
sizeChanged(super.getWidth(), super.getHeight());
}
// paint your user interface
// ...
}
}
I've blogged about this at http://smallandadaptive.blogspot.com.br/2011/04/sizechanged-not-called.html

Drawing lines in MFC VS2010 and VC++6.0 doesn't get the same result

I have been learning MFC these days.I want to draw lines with MoveTo() and LineTo() functions both in VC++6.0 and VS2010,but it seems that it does not work in vs2010.I only add two windows message handler,WM_LBUTTONDOWN and WM_LBUTTONUP,in the single document project.
Here is the code in VC++6.0:
CPoint m_ptOrign;
void CStyleView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptOrign=point;
CView::OnLButtonDown(nFlags, point);
}
void CStyleView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
dc.MoveTo(m_ptOrign);
dc.LineTo(point);
CView::OnLButtonUp(nFlags, point);
}
Here is the code in vs2010:
CPoint m_ptOrign;
void CStyleView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptOrign=point;
CView::OnLButtonDown(nFlags, point);
}
void CStyleView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
dc.MoveTo(m_ptOrign);
dc.LineTo(point);
CView::OnLButtonUp(nFlags, point);
}
The codes I add to the two projects are the same.When I release the left button ,the line appears immediately in the vc++6.0 project,but it doesn't appear in the vs 2010 mfc project.
If the size or location of the window of the vs 2010 project changes,the line apprears.
But when I use dc.Rectangle(CRect(m_ptOrign,point)) in the vs 2010 project ,it works well.
I do not know why.....
What's more,if I use
CBrush *pBbrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
dc.SelectObject(pBbrush);
dc.Rectangle(CRect(m_ptOrign,point))
in vs2010,it does not work again,like the drawing line case
LineTo is going to use the pen that is currently selected into the DC. Since you haven't selected a pen, it will use whatever is the default. I don't know why that would be different between VC6 and VC2010, perhaps it has something to do with the differences in MFC between the two versions.
In general it's a bad idea to grab a DC and start drawing on it. Better is to do all your drawing in the OnPaint or OnDraw methods. You can call InvalidateRect to cause a paint message to be sent to the window.

Resources