Zapisuje wskaźnik funkcji do struktury a po wyjściu z konstruktora on znika

0

Hej! :)
W klasie w sekcji private mam strukturę

struct sSEARCHEDIT sSearchStruct; 

zawierającą m.in 2 wskaźniki na funkcje.

GETSIZE_PROC_TYPE myf_GetSize;
GETSTRING_PROC_TYPE myf_GetString; 

W konstruktorze klasy po "wynullowaniu" wszystkich wskaźników, aby nie zawierały przypadkowych adresów ustawiam wskaźniki zgodnie ze strukturą wysłaną jako argument dla konstruktora:

if(wsk != NULL)
{
    sSearchStruct.myf_GetSize = wsk->myf_GetSize;
    sSearchStruct.myf_GetString = wsk->myf_GetString;
} 
typedef int( * GETSIZE_PROC_TYPE)(void);
typedef void( * GETSTRING_PROC_TYPE)(int index, string &tekst, int &liczba); 

Po tym sprawdzam czy wskaźniki na funkcje nie są "NULL" i faktycznie nie są. Dane do struktury zapisują się prawidłowo.

Do czasu wywołania funkcji f_LSB_FillMap() z wewnątrz klasy nie używam ani nie zmieniam wskaźników na te funkcje.
W funkcji f_LSB_FillMap() zanim nie wywołam tych funkcji sprawdzam czy nie są NULL i tu niespodzianka:
Warunek:

if(!sSearchStruct.myf_GetSize || !sSearchStruct.myf_GetString) 

zwraca mi true i funkcja kończy się niepowodzeniem. Ktoś może mi powiedzieć o co może chodzić? Wskaźnika na funkcje uzywam tylko i wyłącznie w konstruktorze ustawiając go i w funkcji f_LSB_FillMap() więc nie ma możliwości przypadkowego wyzerowania.

0

Chcesz pod wskaźnik do funkcji wsadzić wskaźnik do metody, to czemu się dziwisz?

0

Nie nie, do kontruktora przekazuję funkcje nie metody

 
void GetWord(int index, string &tekst, int &liczba){
    auto it = myMap.begin();
    for(int n=0; n<=index; ++n)
    {
        if(it == myMap.end())
         return;
        if(n == index)
         tekst = (*it).first;
        ++it;
    }
}
int GetSize(){
    return myMap.size();
}

O te dwie

EDIT:
Dod. informacje:

class SEARCHEDIT{
    public:
        SEARCHEDIT(sSEARCHEDIT *wsk); 
struct sSEARCHEDIT{
    GETSIZE_PROC_TYPE myf_GetSize;
    GETSTRING_PROC_TYPE myf_GetString;

    sVSCROLLBAR myVScrollBar;
    LISTSCROLLDRAW myListScrollDraw;
    COLORREF ColBackroundEdit;
}; 

A w pliku main.cpp

sSEARCHEDIT sSearchStruct;
    sSearchStruct.ColBackroundEdit = RGB(0,0,0);
    sSearchStruct.myf_GetSize = GetSize;
    sSearchStruct.myf_GetString = GetWord;
    sSearchStruct.myListScrollDraw = NULL;
    sSearchStruct.myVScrollBar.hInstance = NULL;
    sSearchStruct.myVScrollBar.myDown = NULL;
    sSearchStruct.myVScrollBar.mySb = NULL;
    sSearchStruct.myVScrollBar.mySuwak = NULL;
    sSearchStruct.myVScrollBar.myUp = NULL;

    myEdit = new SEARCHEDIT(&sSearchStruct);
    myEdit->Create(140, 10, 200, 20, 10, hwnd); 
0

Ma ktoś jakis pomysł, bo juz straciłem noc na szukanie błędu i parę godzin dnia dzisiejszego :( wysiadam siłowo

1

Masz trzy możliwości:

  1. Zgłosić się do wróżbitów
  2. Debugier do ręki i wyśledź problem
  3. Podaj kod który jest wystarczający aby go skompilować nie zbyt długi aby nie zniechęcał na wstępie zaś pokazuje problem.
0

SEARCHEDIT.h
http://pastebin.com/yrVTNGvG
SEARCHEDIT.cpp
http://pastebin.com/Wh3n1GZC

Po wciśnięciu klawisza ENTER w RichEdicie z pomocą SubClassingu wysyła się komunikat o wciśnięciu tego klawisza i wywołanie funkcji f_LSB_FillMap()

0

Jeżeli chcesz skompilować to w załączniku jest .rar z programemm całym. Mi się kompiluje bez żadnego warningu

0

Debugger wskazał na to, niestety nie wiem jak to ugryźć (pozwoliłem programowi wysypać się)
<image>983e6bc04c.png</image>

I znów wskazuje, że itoa() jest niezadeklarowane :c usiąść i płakać.

0

teraz pozostało tylko to co niezbędne.

  1. W main.cpp tworze klasę i wysyłam strukturę do konstruktora.
  2. (SearchEdit.cpp) W konstruktorze przypisuję adresy funkcji pobrane ze struktury wysłanej jako argument do konstruktora do struktury wewnątrz klasy.
  3. (SearchEdit.cpp) W Funkcji f_LSB_FillMap() próbuje wywołać funkcję GetSize() ze wskaźnika jednak wskaźnik jest NULL.
0

Znalazłem błąd.
Do poprawnej obsługi procedury SubClassingu richedita musiałem zapisać tę oto strukturę za pomocą SetWindowLongPtr()

struct sSUBPROCSTRUCT{
    WNDPROC ParentProc;
    WNDPROC oldProc;
    SEARCHEDIT *wsk;
}; 

aby móc przesyłać dalej komunikat do domyślnej procedury RICHEDITA albo wysłać komunikat do mojej kontrolki o tym że w richedicie kliknąłem ENTER i chcę wywołać ową funkcję tworzącą LISTSCROLL.

Problem leżał w tym, że w procedurze Subclassingu wysyłałem komunikat nie za pomoca SendMessage tylko
return CallWindowProc. Poprawiłem i śmiga. Dodatkowo to nie usuwało mi danych ze struktury, ponieważ funkcja działała prawidłowo wywołując ją z main.cpp więc "nie wiem co jest grane ale działa" :)

EDIT:
Hmm... albo może i wiem...

return CallWindowProc(wsk->ParentProc, hwnd, WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWLP_ID), SEID_VK_RETURN), 0 ); 

Mam swoją kontrolkę i kontrolke podrzedną richedit.
Co się stanie jak wywołam CallWindowProc podając procedurę mojej kontrolki i uchwyt richedita?

1 użytkowników online, w tym zalogowanych: 0, gości: 1