|
Hi,
Some ideas for 2) and 3):
2) I think you can't have common dialogs and system dialogs in a language different from the OS's language.
3) Use GetLocaleInfo() with LOCALE_SMONTHNAME1-12 to get the names of the months. You can also get name of tha days and other things with proper flags.
Cheers,
Paolo
------
"airplane is cool, but space shuttle is even better" (J. Kaczorowski)
|
|
|
|
|
Hi,
I've read a few about the .inf file format and the setup API functions and
I'm trying to make a tiny little application for practice. But I couldn't
for my life make something that actually works. I attached you the inf and
the code that deals with it. I hope it will not bore you because I
desperately need enlightenment on what am I doing wrong.
If you don't feel like following the flow, could you please give me a working
example as simple as possible of copying a file through .inf files.
Thank you in advance
UINT CALLBACK EmptyHandler(
PVOID Context, //context used by the callback routine
UINT Notification, //notification sent to callback routine
UINT Param1, //additional notification information
UINT Param2 //additional notification information
);
void CFirstPrinterDlg::OnButtonTestMyInf()
{
// TODO: Add your control notification handler code here
UINT nErrLineNo;
HINF hInfFile = SetupOpenInfFile ("d:\\druckertest\\gogo.inf",
"Printer", INF_STYLE_WIN4, &nErrLineNo );
if( hInfFile == INVALID_HANDLE_VALUE ){
ErrorMessage( "SetupOpenInfFile()" );
if( ERROR_NOT_ENOUGH_MEMORY != GetLastError() ){
CString s;
s.Format( "Error at line no %u", nErrLineNo );
AfxMessageBox( s );
}
return ;
}
if( FALSE ==
SetupSetDirectoryId( hInfFile, 66000,
"d:\\druckertest\\output" )
){
ErrorMessage( "SetupSetDirectoryId()" );
return;
}
/*
BOOL SetupGetSourceFileLocation(
HINF InfHandle, // handle of an INF file
PINFCONTEXT InfContext, // optional, context of an INF file
PCTSTR FileName, // optional, source file to locate
PUINT SourceId, // receives the source media ID
PTSTR ReturnBuffer, // optional, receives the location
DWORD ReturnBufferSize, // size of the supplied buffer
PDWORD Required Size // optional, buffer size needed
);
*/
UINT nID;
TCHAR buffer[ 1000 ];
DWORD required;
if( FALSE ==
SetupGetSourceFileLocation(
hInfFile,
NULL,
_T( "file.txt" ),
&nID,
buffer,
1000,
&required
)
){
DWORD n = GetLastError();
DWORD k = GetLastError();
ErrorMessage( "SetupGetSourceFileLocation()" );
//return;
}
int a;
BOOL bRes = SetupInstallFromInfSection( NULL, hInfFile,
"[INSTALL]", SPINST_FILES, NULL, "D:\\druckertest",
SP_COPY_DELETESOURCE, EmptyHandler,
&a, NULL, NULL );
if( bRes == FALSE ){
ErrorMessage( "SetupInstallFromInfSection()" );
return ;
}
SetupCloseInfFile( hInfFile );
return ;
}
And gogo.inf is:
[VERSION]
Signature="$Windows NT$"
Class = Printer
Provider = LukeNuke
[INSTALL]
CopyFiles = @file.txt
[DestinationDirs]
DefaultDestDir=66000
[SourceDiskFiles]
file.txt = 1
[SourceDiskNames]
1 = "LukeNuke",*.*
|
|
|
|
|
Anyone know how to add a command ID with a set value of 8000? or better still, allocate a set range of command ID's from 8000 to 8049, so that only i can allocate these ID's at runtime? How would I then go about adding dynamic command id's at run-time so that they fall within the specified range? The problem I have is that I am using UINT as a way of assigning a menu item its ID. However, the status bar does not display any text when i move the mouse over the item, nor is there any assurance that that ID hasn`t been used elsewhere in the program, which would cause undesirable results.
Theres definitely a "This helped" going on this one.
AEGC
|
|
|
|
|
What determines the existance of a given menu item? The presence of a DLL? A registry entry?
If it's the presence of a DLL, maybe all your DLL's should have an exported function that can provide the program with the following associated info:
- Menu item ID
- Menu item name
= tooltip text
- status line text
All installed DLL's should be listed in the registry and when the program attempts to call LoadLibrary, each DLL can be queried for the data (as opposed to putting that data in the registry as well). Since you're writing the DLL's, it would be up to you keep the various ID's, names, and text unique, but that shouldn't be too god awful tough.
If it were me, I'd establish (in my app) a minimum ID and a maximum ID so that I could use that range in my ON_COMMAND_RANGE handler. Remember, just because it handles a range of ID's doesn't mean they all have to be used.
Also, I would makes sure that range of command ID's are not used by other resources.
I know this response was a broad contextual overview of the procedure, but you should be able to work with what I've suggested if you're at all experienced in writing DLLs and accessing the registry.
Unfortunately, there's no automatic method for doing what you want to do (compartmentalizing resource ID usage) - it's grunt work that must remain grunt work.
To hell with those thin-skinned pillow-biters. - Me, 10/03/2001
|
|
|
|
|
The command id number is controlled by the resource.h file.
#define _APS_NEXT_CONTROL_VALUE 201
You can modify the value of this constant and new commands will be created with the new base number. If you look in your <projectname>.res file you will see the control ids already defined. These too can be edited. Be careful, however not to bump into system command IDs or other confilcts. Also be aware, the IDE will assign control ids based on the defined constant. So if you just make some up, you mus change the constant to ensure the number won't be reused.
Hope this helps,
Bill
|
|
|
|
|
I believe he wants to generate these ID's at runtime.
To hell with those thin-skinned pillow-biters. - Me, 10/03/2001
|
|
|
|
|
Your are right, I missed that.
Thanks for the help,
Bill
|
|
|
|
|
Once you have used ON_COMMAND_RANGE etc to map where the messages goto, you can use CMainFrame:GetMessageString to provide the status bar prompt and tooltips.
Example code from an app of mine is:
void CMainFrame::GetMessageString( UINT nID, CString& rMessage ) const
{
if (nID >= REFINESCRIPT_MENU_START_ID && nID <= REFINESCRIPT_MENU_END_ID)
{
rMessage = refineDLL[theApp.nIDtoRefineID[nID - REFINESCRIPT_MENU_START_ID]].DLLMenuStatusBarPrompt(nID /*theApp.nIDtoMenuID[nID - REFINESCRIPT_MENU_START_ID]*/) ;
// remove any tooltip
if (rMessage.Find('\n') >= 0)
rMessage = rMessage.Left(rMessage.Find('\n')) ;
}
else if (nID == ID_TOOLBAR_UNDO || nID == ID_TOOLBAR_REDO)
{
// need to get the active document
CDocTemplate *pTemplate;
CRefineDoc *pDoc = NULL ;
POSITION pos;
bool found = false ;
pos = AfxGetApp()->GetFirstDocTemplatePosition();
do {
pTemplate = (AfxGetApp()->GetNextDocTemplate(pos));
POSITION pos2 ;
pos2 = pTemplate->GetFirstDocPosition();
if (pos2 != NULL)
{
// loop through looking for the active docuement
do {
pDoc = (CRefineDoc*)pTemplate->GetNextDoc(pos2);
if (pDoc->m_bActiveDocument)
found = true ; // found it!
} while (!found && pos2 != NULL) ;
}
} while (!found && pos != NULL) ;
if (pDoc != NULL)
{
CString command ;
if (nID == ID_TOOLBAR_UNDO)
{
// get the undo message text
pDoc->GetUndoText(command) ;
rMessage.Format("Undo command \"%s\"", command) ;
}
else
{
// get the redo message text
pDoc->GetRedoText(command) ;
rMessage.Format("Redo command \"%s\"", command) ;
}
}
else
CMDIFrameWnd::GetMessageString(nID, rMessage) ;
}
else
{
// check to see wether the nID is part of one of the loaded toolbars.
// it it is, we need to load the string from that dll's resources
bool found = false ;
for (int i = 0 ; i < m_ToolbarCount ; i++)
{
if (m_pTB[i]->CommandToIconIndex(nID) >= 0)
{
found = true ;
// get the string from the DLL
rMessage = refineDLL[m_DLLIndexes[i]].DLLMenuStatusBarPrompt(nID) ;
// split the text at an \n
if (rMessage.Find('\n') >= 0)
rMessage = rMessage.Left(rMessage.Find('\n')) ;
}
}
if (!found)
CMDIFrameWnd::GetMessageString(nID, rMessage) ;
}
}
In the function:
REFINESCRIPT_MENU_START_ID = start of the command range allocated
REFINESCRIPT_MENU_END_ID = end of comamnd range allocated
The above code is used in a project where dynamically loaded DLL's are used, which also add menu options etc in. New toolbars may also have been added to the UI.
Hope its of help.
BTW GetMessageString is a virtual function you can override
|
|
|
|
|
I'd use AfxExtractSubString (just like MFC does) for extracting status bar prompt
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Can anyone please tell me how to make a CFormView object to
a non resizable window?
Thanks.
Aviv.
avivhal
|
|
|
|
|
Override the OnSize() message in your view and just don't pass the message on to the base class.
You may have to have a variable that indicates that the window is being initialized so that you can pass the size info along, and NOT to pass it along any other time.
1) Define a private boolean var in your class definition like so:
BOOL m_bAllowResize;
2) In the view constructor, do this:
m_bAllowResize = TRUE;
3) At the end of OnInitialUpdate() do this:
m_bAllowResize = FALSE;
4) In your OnSize function, do this:
if (!bAllowResize) { return; }
I haven't tried this, and you may have to try moving some of the code I listed above around in the class, but in theory, this should be close to what you want.
To hell with those thin-skinned pillow-biters. - Me, 10/03/2001
|
|
|
|
|
Hi,
I used these functions in a demo project:
void CDemoView::FormViewToDialog()
{
CWnd* pParent = GetParent();
CRect rect;
GetTotalClientRect(&rect);
DWORD style = pParent->GetStyle() & ~WS_THICKFRAME | WS_DLGFRAME;
::AdjustWindowRect(&rect, style, ::IsMenu(::GetMenu(pParent->GetSafeHwnd())));
ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
pParent->ModifyStyle(WS_THICKFRAME, WS_DLGFRAME);
pParent->SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
}
void CDemoView::DialogToFormView()
{
CWnd* pParent = GetParent();
CRect rect;
GetTotalClientRect(&rect);
DWORD style = pParent->GetStyle() & ~WS_DLGFRAME | WS_THICKFRAME|WS_CAPTION;
::AdjustWindowRectEx(&rect, style, ::IsMenu(::GetMenu(pParent->GetSafeHwnd())),
WS_EX_CLIENTEDGE);
ModifyStyleEx(0, WS_EX_CLIENTEDGE);
pParent->ModifyStyle(WS_DLGFRAME, WS_THICKFRAME|WS_CAPTION);
pParent->SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
}
Paolo
------
"airplane is cool, but space shuttle is even better" (J. Kaczorowski)
|
|
|
|
|
Ahhh, I knew someone would post the right way to do it.
To hell with those thin-skinned pillow-biters. - Me, 10/03/2001
|
|
|
|
|
Always happy to help.
Thanks John!
------
"airplane is cool, but space shuttle is even better" (J. Kaczorowski)
|
|
|
|
|
Christian, your last message was
>>The thing you have to consider is, what do you want to achieve ? The way
>>you're writing the file, you're getting an 8 bit greyscale image, if you
>>put this info into an 8 bit bitmap with a palette that went evenly from
>>0,0,0 to 255,255,255, it would work. You're only writing out one colour
>>value as far as I can see, and you're now correctly calculating the grey
>>value. Therefore making your bitmap 8 or 16 bit internally will only result
>>in messy calculations to get to the same point you're reaching now. Please
>>correct me, but I believe you're writing out one unsigned char per colour,
>>although you're making the variable an unsigned long, it will still be
>>between 0 and 255, yes ?
Yes, it still between 0...255.
And more, i compared it for 24 and 32 bpp with using GetPixel function
BYTE grayValue = (BYTE)(int)((GetRValue(clr) + GetGValue(clr) + GetBValue(clr)) / 3),
and it was the same.
But for 8 bitmap, then i using GetPixel it was like
125 125 125 (Red Green Blue)
and for my code it was
31 31 31
Why? I don't know
Yes, i need grayValue for every pixel
But i don't neen GetPixel(), because it work with handle (hDC, DC and other),
i need information only from bitmap (avi frame->LPBITMAPINFOHEADER)
But i haven't ideas how to wrote simple code for 8 and 16 bpp
|
|
|
|
|
So you're storing the bitmaps as *well* and therefore want to be able to read them regardless of format ? GetPixel() will work, albeit slowly. I'm about to go to work, but I'll dig up some code from my paint program tonight to get the info you need in order to convert 8 and 16 bit values into an RGB value.
Christian
After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
|
|
|
|
|
Thanks a lot, Christian!
My email mrserg@aha.ru or mrserega@aha.ru
|
|
|
|
|
|
Hello!
I'd like to know how do I add a popup menu in a CTreeCtrl
TY
|
|
|
|
|
|
- The following statements are taken from MSDN(Ti: LoadLibrary)
The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary or LoadLibraryEx. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread).
- I do not understand what means "explicitly" here? Why should we use thread local storage functions other than thread-local variables?
- Can you help?
Thanks,
Maer
|
|
|
|
|
'Explicit' loading means that your app uses LoadLibrary[Ex] to bring a DLL into process adress space at some point of execution. You have to get the address of exported procedure[s] later with a call to GetProcAddress.
OTOH, 'implicit' loading (for which __declspec(thread) works correctly) means that system loader will load .dll automatically at the program startup --and-- it will resolve references to exported functions. You just need to link with import library to make this happen. No LoadLibrary, no GetProcAddress.
Now, the __declspec(thread) problem - there's some magic going on during the program startup. The C Runtime creates some thread-local storage space and puts the variables marked as __declspec(thread) there. This happens when all implicitly loaded .dlls are already in place. If you load .dll explicitly later with __declspec(thread) variables, there may be no space left - the C runtime doesn't know you've loaded some .dll. In such case, you have to use TlsXXX functions provided by Windows 'manually'.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
- The TLS is the local storage of a thread. Suppose a thread loads a Dll. Then the Dll will initialize the TLS.
- I think the TLS belongs to thread and not belongs to Dll. So I do not understand why should Dll do the initialization task.
- Since the TLS belongs to thread, I think it is the job of thread to do the initialization of the TLS.
- Can you help?
Thank,
Maer
|
|
|
|
|
Well, the thread is doing the initialization of it's TLS. And it is doing it by executing the code contained in the DLL. Remember, the code in the DLL (or in any other place in your program, for that matter) can be executed by any thread in your program - you cannot say that any code belongs to any specific thread. The key term here is that the code is executed in the context of a thread. The same code can be executed in the context of different threads - it can even be executed simultaneously, leading to multithreading issues if you don't protect your data structures. And using TLS is one way of separating thread-specific data from the rest.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
bla
Don't open your mouth, unless you have to say something.
|
|
|
|
|