|
1. Define exactly what you mean.
2. If you mean at the application level then analyze the application to find how input is handled. If at the OS level then read up on how to create input handlers (drivers.) Depending on what 'key' you want to disable then this might require different approaches.
3. Write the code
4. Test it.
|
|
|
|
|
Technically, the C programming language has no such provisions. You will need to interact with the hardware using specific APIs.
Now depending on how you answer Victor's question, there may be a solution to the question you meant to ask.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
I indent to use FindFirstChangeNotification in a class static method in order to use it in a thread, something like this:
DWORD WINAPI FilesWatchDogThread(LPVOID lpParam)
{
HANDLE hFileChange = ::FindFirstChangeNotification((LPCTSTR)lpParam, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME);
if(INVALID_HANDLE_VALUE == hFileChange)
{
DWORD dwError = ::GetLastError();
return dwError;
}
while(TRUE)
{
::WaitForSingleObject(hFileChange, INFINITE);
::FindNextChangeNotification(hFileChange);
}
return 0;
}
::CreateThread(NULL, 0, &CMyClass::FilesWatchDogThread, _T("c:\\temp"), 0, NULL);
but how can Itell the thread when a folder to watch has been changed (I mean _T("c:\\temp") change to _T("e:\\whatever")) ? What should I use for that ? CreateEvent or what ?
|
|
|
|
|
Yes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder.
Note, that thread must now wait for multiple objects!
|
|
|
|
|
Thank you Victor, can you elaborate a little bit ? Even some pseudo-code will be good 
|
|
|
|
|
Have a look at the WorkerThreads essay of Joe Newcomer.
It is MFC issue, but the main concept is the same as for plain Win32 API. Just look at the sections:
Pausing a Thread and Thread Shutdown
Shutting down a thread from a view or main frame
Thread Shutdown Without Polling
(Well, you would need something similar to "Pausing" event.
|
|
|
|
|
I have two questions:
1. Why should I use CreateEvent, and if I should, where ?
2. Why should I use WaitForMultipleObjects instead of WaitForSingleObject ?
|
|
|
|
|
- to inform the worker thread that it must do something (to change the folder in your case). CreateEvent/SetEvent - in the main thread.
- Because there is already one object: hFileChange. However the thread should react also to the second object created/set by CreateEvent/SetEvent in the main thread.
|
|
|
|
|
There will be ideal a little code 
|
|
|
|
|
Ask and you shall receive .. that is it straight on the windows API.
GitHub - LdB-ECM/FolderWatcher[^]
There is both the detailed and basic thread monitor code.
There is a compiled exe in release/debug if you just want to run and see it.
In vino veritas
|
|
|
|
|
Here is what I've done:
protected:
CEvent m_event;
CString m_sFolder;
CWinThread* m_pWinThread;
UINT CTestFileView::FilesWatchDogThread(LPVOID lpParam)
{
CTestFileView* pView = (CTestFileView*)lpParam;
if (NULL == pView->GetSafeHwnd())
return 1;
HANDLE hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
if (INVALID_HANDLE_VALUE == hChange)
return 1;
HANDLE aHandles[2];
aHandles[0] = hChange;
aHandles[1] = pView->m_event.m_hObject;
BOOL bContinue = TRUE;
while (bContinue)
{
DWORD dwResult = WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);
switch (dwResult)
{
case WAIT_OBJECT_0:
::PostMessage(pView->GetSafeHwnd(), WMU_NOTIFY_FOLDERCHANGED, 0, (LPARAM)0);
FindNextChangeNotification(hChange);
break;
case WAIT_OBJECT_0 + 1:
bContinue = FALSE;
break;
}
}
FindCloseChangeNotification(hChange);
return 0;
}
and
void CTestFileView::StopThread()
{
m_event.SetEvent();
WaitForSingleObject(&m_event, INFINITE);
}
and
void CTestFileView::OnEditStartthread()
{
m_event.ResetEvent();
m_sFolder.Format(_T("D:\\Tempx\\"));
m_pWinThread = AfxBeginThread(&CTestFileView::FilesWatchDogThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED, 0, NULL);
}
there is remain one thing to do: to change the folder (m_sFolder) how can I complete this with CreateEvent/SetEvent ?
|
|
|
|
|
"Go to ParentYes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder"
To create a third event which stop the thread and restart FilesWatchDogThread method with new folder value ?
|
|
|
|
|
yes, you create the third event and NOT to stop thread, but to change the folder!
Something like:
case WAIT_OBJECT_0 + 2:
FindCloseChangeNotification(hChange);
hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
aHandles[1] = pView->m_event.m_hObject;
And don't forget to set the new folder from the main thread BEFORE setting this event!
|
|
|
|
|
Do you meant
aHandles[0] = hChange;
instead of
aHandles[1] = pView->m_event.m_hObject;
?
|
|
|
|
|
Yes! Sorry for the typo!
|
|
|
|
|
I have a MFC app which list some files (from an HDD folder) into a CListCtrl. Is there any windows message to know when a files was deleted/copied with other app (e.g. Windws Explorer) from that folder where I listed the files ? I need that message in order to handle it to refresh my file list ...
|
|
|
|
|
|
|
There is nothing that will tell you when a file is "copied". There is really no such operation. All a copy is is a file being opened for read and another being opened for write. The bytes in the first file are read and then written to the second file. You cannot get a notification of the read but you can for the file being created. See the links the other have posted for that.
|
|
|
|
|
I have 3rd party . OCX file. which loads in HTML scripts and do desired work
Below Steps I have used while creating a Wrapper:
1: In visual Studio-> VC++-CLR-ClassLibrary project
2: Project add Reference (.ocx file)
3: Ref: i am abe to see Interop.Filelib.1.0
4: now in Project.h i am trying to use Filelib but not able to create any object or instance.
While i tried to create an Activex project and added .ocx file getting below stuff and i am not able to understand how to use it and create an wrapper for C#.
class CDNXCardReaderX : public CWnd
{
protected:
DECLARE_DYNCREATE(CDNXCardReaderX)
public:
CLSID const& GetClsid()
{
static CLSID const clsid
= { 0x222BBB5D, 0xE9FC, 0x4EB6, { 0x9E, 0xD0, 0x41, 0x10, 0x2C, 0x95, 0xC0, 0x3A } };
return clsid;
}
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID,
CCreateContext* pContext = NULL)
{
return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID);
}
BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE,
BSTR bstrLicKey = NULL)
{
return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
pPersist, bStorage, bstrLicKey);
}
public:
public:
long OpenSessionSync(long Timeout)
{
long result;
static BYTE parms[] = VTS_I4 ;
InvokeHelper(0x2d, DISPATCH_METHOD, VT_I4, (void*)&result, parms, Timeout);
return result;
}
I am totally clueless on what approach shall i use to create object and call these functions.
|
|
|
|
|
|
I got your point. here i tried to get the object from my ocx and tried to access the functions but I am failing to do so i feel the issue is because of
IMPLEMENT_DYNCREATE(CMFCActiveXControl1Ctrl, COleControl)
looking for a sample code if any.
|
|
|
|
|
Gaurav__Kapoor wrote: i feel the issue is because of Forget what you feel and study the documentation. That is the only way to understand the code.
|
|
|
|
|
I'm writing code for a microcontroller in standard C and I'm compiling with GCC. My product has registers with addresses:
enum regAddr_e {
REG_A = 0,
REG_B = 2,
REG_C = 4
};
typedef struct {
regAddr_e regAddr;
uint16_t regValue;
} regAddrAndValue_s; When I want to write to registers, I create an array of regAddrAndValue_s and pass it to my write function. However, I have found that I quite often write to consecutive addresses so a lot of times only the start address would be needed:
typedef struct {
regAddr_e startRegAddr;
uint16_t regValues[];
} consecutiveRegAddrAndValues_s; However, as a documentation I would like to keep all registers visible in the code. So, I would like have a macro that does something like this:
#define MY_CLEVER_MACRO(__NAME_OF_STRUCT_VARIABLE__) \
REG_A, 0x0123, \
REG_B, 0x04567, \
REG_C, 0x89AB The macro should produce:
consecutiveRegAddrAndValues_s __NAME_OF_STRUCT_VARIABLE__ = {REG_A, {0x0123, 0x4567, 0x89AB}}; Also, if someone changes the register addresses so that a range is no longer consecutive, then I would like to throw a compile-time static_assert. Can someone please help me what MY_CLEVER_MACRO should look like?
|
|
|
|
|
If you want to 'document' where you're writing to, why not just provide several functions that offer this information right in their name? E. g.;
void setreg_A(uint16_t aval);
void setreg_B(uint16_t bval);
void setreg_C(uint16_t cval);
void setreg_all(uint16_t aval, uint16_t bval, uint16_t cval);
If that isn't what you want, what is? Can you show a line of code that would invoke your 'clever macro'? It's hard to say what is your intention without seeing how you're going to use it.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|