|
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)
|
|
|
|
|
Just experienced an interesting behavior of my code AFTER getting cute and using "socket" for name of the return from
hci_open_dev .
The particular return was really described as "socket" - connection between processor and bluetooth "adapter" - but was originally named "sock".
After much search I realized that "hci" API names the return
"device descriptor"
and other known "opening device" function calls it "file descriptor".
Then I discovered "file handle " !
Is "handle" an ancient "windows OS" term ?
After this unpleasant experience I'll definitely NOT name anything "socket" , but I am curious what name would be really descriptive ( no pun intended ) for the return of generic "open_x" function ?
dev_descriptor = hci_open_dev(dev_id);
And if you feel it is a matter of personal preference, you do not need to state that.
Maybe it is covered in today's "ANSI C standards" - if there is such a thing.
Cheers
|
|
|
|
|