|
i am learning windows programming using Visual Studio .NET and i am having a problem with ShellExecute.
i have written a small tabbed window that shows shortcuts using Qt 3.2 (from Trolltech). the program is simply a convenient way of showing a selection of shortcuts for me to click on.
when i get a click, i run:
ShellExecute(NULL, "open", pszShortcut, NULL, NULL, SW_SHOWNORMAL);
where pszShortcut is a NULL terminated char * holding the full file name of a shortcut.
when i use this program to run Visual Studio:
pszShortcut = "D:\Documents and Settings\colin.MICROTEST.CO.UK\Tab Launchpad\Applications\Visual Studio .NET 2003.lnk"
VS loads fine, but i cannot compile due to the error:
Project : warning PRJ0018 : The following environment variables were not found:
$(QTDIR)
qt-mt - up-to-date.
QTDIR is defined as a user variable in control panel -> system, and is simply the string "c:\qt\live". if i run Visual Studio from the start menu, or by running my shortcut via windows explorer everything works.
i have also tried:
char *pszTest = getenv("QTDIR");<br />
qDebug("about to run, qtdir = {%s}", pszTest ? pszTest : "NULL");<br />
ShellExecute(NULL, "open", pszShortcut, NULL, NULL, SW_SHOWNORMAL);<br />
and the QTDIR environment variable is correctly returned.
it is as if the ShellExecute call is stripping some of the environment variables
i am starting to feel very out of my depth, so any help would be greatly appreciated. i am getting the same problem at work (winXP pro, VS .NET 2003) and at home (winXP pro, VS .NET, the one before 2003) so it isn't a machine specific problem, and i haven't been able to find any hints in the help or via google.
|
|
|
|
|
Somewhere in your project settings you try to load the environment variable $(QTDIR) which isn't possible (as far as I know atleast). You can only use the predefined variables, ie:
$(ConfigurationName)
$(PlatformName)
....
$(WebDeployPath)
$(WebDeployRoot)
etc. One thing is for sure. It hasn't got the slightest connection with your code It's just the project settings that cause the problem.
|
|
|
|
|
ah, um... *starts to get concerned i am doing impossible things, again*
in my project settings i have:
C/C++ -> General -> Additional Include Directories = $(QTDIR)\include
to be honest i am not sure why, but this is how i was told to set up a windows project. i have found you do have to reboot after adding the user environment variable in order for visual studio to detect it.
are there any "oddities" with ShellExecute that i should know about? i have a separate problem with my program because if i execute a shortcut to my Dialup Network connection (on my home machine) it doesn't do anything
thanks for the reassurance about my code
|
|
|
|
|
Well if they tell you that's the way to set up the project, I guess they are correct. Perhaps you've made a mistake in declaring it as a user variable instead of system variable or vise versa? Also if you are going to change the install directory of QT anyway, why bother and not just put the full path as include directory
|
|
|
|
|
i had another look at this last night. i loaded VS 6 times via my program, and about half the time it worked, and the other half the time the environment variable was undefined
so, i have simply removed the references to QTDIR in the project settings and used the directory instead. i would like to know what the problem was, but i am not sure i want to give the time and effort it would take. i will focus on more interesting and productive things instead
|
|
|
|
|
I know exactly what you mean. One part of you wishes to figure out what causes the problem, but that other part tells you to move on and work as you are running out of time Somehow though I most of the times tend to do the problem solving anyway...
|
|
|
|
|
Hi,
I have a control with a listbox and an edit on it. The control can be resized and both controls get resized as well. I checked my program with boundschecker and it found a resource error in each of those controls. It calls ReleaseDC while there are still non-stock objects in it. Well I checked and rewrote my drawing code like 10 times and it still didn't go away. I -know- it's flawless. So I reproduced the control step by step and noticed the resource error wasn't there when I didn't have the listbox on my control. Huh? So step by step I traced the error to the point that I resize the listbox.
Every time I resize the listbox my DC gets corrupted. Well I looked at the class styles of the listbox, and indeed it has the CS_PARENTDC style, so it could be very well possible that the listbox is the cause of my problem. But, here's the catch. It's just a stock listbox. I didn't do anything with it, straight from the Win32 API Did anyone else notice this error by Microsoft or am I overlooking something and is it a mistake made by myself?
To reproduce:
- Make a window
- Add a listbox
- On resize, resize the listbox
- Make sure you call both GetDC() and ReleaseDC() in any paint event (doesn't even have to be a paint event I suppose) of the window (you don't have to actually draw something, it just matters to call ReleaseDC() so boundschecker jumps in)
- Run boundschecker and resize the window a bit, it will trigger the error eventually
I tracked it even further. The following messages generate the error:
WM_NCPAINT
WM_ERASEBKGND
So what I did to solve it is to subclass the listboxes and handle these messages. Then I do the following:
LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&) throw()
{
HDC hDC = ListBox.GetWindowDC();
int nSaved = ::SaveDC(hDC);
ListBox.DefWindowProc(uMsg, wParam, lParam);
::RestoreDC(hDC, nSaved);
ListBox.ReleaseDC(hDC);
return 0;
}
It works, but I don't like it that I have to do this to solve a problem which shouldn't be solved by me at all and neither to solve it this way. So again, does anyone have the same problems I have and if so how did you solve it?
|
|
|
|
|
Does this cause problems other than boundschecker complaints ? (gdi resource leaks ?)
|
|
|
|
|
Well it's quite simple. Boundschecker tells me that there are non-stock objects inside the DC. This means that there are objects created, selected and not removed and destroyed. I can't verify if they ever get destroyed as boundschecker doesn't check the windows code (I assume atleast). So there might just be a chance that there is a resource leak indeed...
|
|
|
|
|
Can someone please clear my confusion about the major function calls related to WM_PAINT and the sequence in which they are called. I want to know when these functions:
OnUpdate
OnInitialUpdate
UpdateAllViews
OnDraw
InvalidateRect
are called - whether before or after WM_PAINT, and in what sequence.
I've read that InvalidatRect just adds the rectangle to the update region, but it seems to me that a call to it also causes the window to be repainted immediately, or in ther words, a WM_PAINT is passed. Is that true?
It would be great if someone can explain me the MFC drawing sequence and procedure in detail. U see, i have just begun with VC and my project is entirely graphics based (OpenGL). So its imperative that i get a good grasp on the drawing mechanism.
Despo for your replys.
Thanks.
|
|
|
|
|
The only virtual methods which are called by the MFC framework are those with OnXXX.
OnInitialUpdate is called after the view is attached to a document but before the view is initially displayed.
OnUpdate is called if you change the document data and call UpdateAllViews. So OnUpdate is called by UpdateAllViews. The default implemenation is also called by OnInitialUpdate and it invalidates the entire client area and so it will be repainted if the next WM_PAINT messages is received.
UpdateAllViews should be called if you changed the documents data and so the view of the document must be marked invalid so that it is repainted in the next WM_PAINT message! So it forces the views of the document to display the changed data.
As I said above UpdateAllViews calls OnUpdate of all views which are attached to this document (except the sender view).
Note: you can prevent that OnUpdate invalidates the whole client area, if you overwrite UpdateAllViews/OnUpdate and pass a hint object with the information which part of the view must be updated in order to refelect the document changes!
InvalidateRect adds the given rectangle to the windows update region. The update region will be repainted if the next WM_PAINT message is received. It is used by OnUpdate to invalidate the given region of the view.
OnDraw will be called by the MFC framework in order to display the document. So OnDraw is called if a WM_PAINT message has been received.
|
|
|
|
|
OnUpdate and OnInitialUpdate are called by the framework. OnInitialUpdate is called when the view is first created, and can be used to perform some initial setup before it then calls OnUpdate.
OnUpdate is called by the framework in response to a call to CDocument::UpdateAllViews. You normally call UpdateAllViews if you've modified something in the document. This allows multiple views of the same document to be updated (maybe you have a CAD drawing, with different view windows showing different viewpoints of the design). UpdateAllViews calls OnUpdate for all views attached to the document, apart from the one passed in the pSender parameter.
CWnd::InvalidateRect is a simple Windows wrapper function (wrapping ::InvalidateRect) which tells Windows that a certain area of the window needs to be redrawn. When your thread's message queue is empty (apart from timer messages, which are the lowest priority), Windows posts a WM_PAINT message for each window that has an invalid region. MFC handles this in CView::OnPaint by retrieving the window's DC, calling OnPrepareDC to allow it to be set up correctly, then calling OnDraw().
OnPrepareDC doesn't do anything in CView's implementation; CScrollView overrides it to set up the scroll extents correctly. This allows you to use a single co-ordinate system whatever the current position of the scroll bars.
OnDraw() is also called when you use MFC's built-in printing support. This enables you to support both drawing to the screen and to a printer using the same code.
Most of the functions you're discussing are implemented in VIEWCORE.CPP. If you haven't installed the MFC source code, you may find it helpful to do so. The book MFC Internals by George Shepherd and Scot Wingo is still a good reference, despite being 8 years old; the core of MFC has barely changed since version 4.0.
|
|
|
|
|
Hi,
Iam Using VC++, Iam planning to capture the screen, saving into .BMP format and iam able to do this.
My question is
I want to capture the screen whenever the changes happen on my desktop.
Can any one tell me how do i know whether the screen changed or not. i mean through which event we can find it out.
Thanks in Advance.
Regards
Santosh.K
|
|
|
|
|
If you wish to capture the screen when even a single pixel has changed you'll have an impossible time finding an event which triggers that. Suppose you have a movie running on the screen. The screen changed but probably not a single message is called. In this case your best bet would be to keep capturing the screen on a certain interval and comparing the bitmaps in memory. This would be really slowing down your system though. If you don't mind much about movies and the like and wish to recapture only when a window for instance resizes or gets created you could make a global windows hook. A CBT hook would be quite good for this purpose I guess.
From the MSDN:
The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue.
|
|
|
|
|
The best thing you can do in this case I guess is to capture the screen at a static interval. You can do three things (which I can think of atleast ):
1) Just capture the screen at a static interval and write it to the disk as bitmap
2) Capture the screen at a static interval and write it to the disk as a compressed image
3) Capture the screen and compare it to the last to see if it changed and write it to the disk if it didn't (this means that you'll also have to keep a log on how long the same image should be shown)
Depending on the desired framerate and quality of the final movie (and ofcourse speed of the machine) I can't do nothing but suggest you to find the best and fastest way for yourself. They all have disadvantages, the first two being a high I/O and the second a lot of CPU required. The third, well I don't know about performance in the third. It seems like it could be pretty fast compared to the other two, but it's just a hunch
I think though that if you want the best performance this should be done in assembly, especially with method 2 and 3.
And I was just thinking. Suppose you have a resolution of 1024x768, 16 bits and you wish to have a framerate of 24. This means that with method 1 you'll have to write about 40MB/s to the harddisk. It's going to have a very hard time doing that and the harddisk will need quite some space too If I were you I'd try my last suggestion, it sure seems like the most fun suggestion as well
|
|
|
|
|
Hi Mr.GopalaKrishna,
Iam Using VC++, Iam planning to capture the screen, saving into .BMP format and iam able to do this.
My question is
I want to capture the screen whenever the changes happen on my desktop.
Can any one tell me how do i know whether the screen changed or not. i mean through which event we can find it out.
Thanks in Advance.
Regards
Santosh.K
|
|
|
|
|
This must be easy i dont know how to do it.
I have a dialog box and a button on the screen,
i want to move th button from one place to another under certain conditon.
Moveing the window is fine no prob.
but i want to do it this way.
first get the current position of the button.
then move the button relative to this position.
I tried GetClientRect and GetWindowRect, but i am not able to use it properly.(may be i am doing it allwrong)
basiaclly i am not able to get the current posion of the button on the dialot.
how do i do that.
thanx.
Toughest Steel Comes From Hottest Furnance
|
|
|
|
|
MoveWindow should help you. You will need to pass the x/y pos or rect details in so getting the rect before you start would help.
BD
|
|
|
|
|
GetWindowRect(hButton,...) will give the position of the button relative to the top left of the screen.
GetWindowRect(hDlg,...) will give the position of the dialog relative to the top of the screen.
Simple maths gives you the position of the button relative to the dialog, or you can use ScreenToClient(hDlg, buttonrect) to convert the button position.
Steve S
|
|
|
|
|
Anyone know if or how I can format cells and skip rows writing out to a spreadsheet (MS EXCEL).
Ger
|
|
|
|
|
|
Check out the MSDN article Q178749.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
Any examples of how I could add filtering to a ListCtrl Column? The only example I can find on the site draws from a 'dead' link.
Ger
|
|
|
|
|
You would filter at the time of calling InsertItem() and/or SetItemText() .
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
Hi,
my program making request to the server on loop first time the request works correctly. rest of the loop the data is read from cache. how to avoid this problem. i need to load each and every time from server. any one help to me.
thanks in advance.
Have A Nice Day!
Murali.M
|
|
|
|