[C++][MFC]ID kontrolek tworzonych dynamicznie

0

Tworząc sobie kontrolki dynamicznie musimy jak wiadomo podać im jakieś id np, żeby utworzyć:

edPercentOfSeg[i].Create( WS_CHILD | WS_VISIBLE | WS_TABSTOP |WS_BORDER,CRect(155,100+i*40,200,130+i*40),this,..............ID..........)

ale w moim programie mam też kontrolki, które wcześniej zostały utworzone z designera i przydzielone im ID jest zdefiniowane w resource.h, jak to obejść? Czy jest jakieś id max i np jako id podawać id_max+i, czy może utworzyć sobie w resource.h jakieś identyfikatory - tyle ile kontrolek tworze automatycznie i potem inkrementowac od min?

0

Zrób sobie statycznego int'a, przy tworzeniu kontrolki dodawaj do niego jeden i używaj jako ID.

0

Tak właśnie zrobiłem :) dzięki :) Mam jeszcze jedno pytanie (trochę na przyszłość), jak teraz przechwytywać zdarzenia z tak utworzonej kontrolki? (dopiero uczę się mfc). I może jeszcze jedno głupie pytanie, szansa, że przekroczy się zakres inta jeżeli dużo razy będzie się coś tworzyć jest nikła? ;p

0
snakeomeister napisał(a)

jak teraz przechwytywać zdarzenia z tak utworzonej kontrolki? (..) szansa, że przekroczy się zakres inta jeżeli dużo razy będzie się coś tworzyć jest nikła? ;p

  1. musisz sie wpiac w petle komunikatow i tam sprawdzac czy id kontrolki wysylajacej komunikat wskazuje na jdena z interesujacych Cie kontrolek. i potem zareagowac zgodnie z wybranym komunikatem..
  2. ze przekroczysz int'a - ciezko powiedziec. zakres +-2mld, do gornych 2mld ciezko bedzie po jednym oczku dojsc, zlezy ILE kontrolek tworzysz i JAK czesto. przelicz sobie. natomiast prawdopodobniejsze jest ze po drodze w gore trafsz na jakis ID nalezacy juz do jakiegos istniejacego elementu - no, chyba ze przypilnujesz aby wszystkie wygenerowane przez visuala kontrolki byly 'ponizej' twoich numerow
0

Ok, dzieki za rade, a co do pkt 2giego to tak, pierwsze id jest wieksze niz wszystkie istniejace kontrolki przeciagniete z toolboxa, poza tym co jakis czas moge przeciez im przywrocic najnizsze id tj powiedzmy ze zaczynam od 5000 i jak dojdzie np do 10k to wtedy z powrotem zaczac od 5?

0

Tak, możesz tak zrobić, ale wypadałoby sprawdzić czy rodzić nie ma już kontrolki o id 5k.
Dajmy na to przedział to 5k-10k. Wybieranie id możesz zrobić tak:

do if(++i == 10k) i = 5k;
while(rodzic_nie_posiada_kontrolki(i));

Wtedy nie musisz się martwić o przekręcenie licznika, a jedyne ograniczenie to max 5k dynamicznych kontrolek na rodzica.

0

Właśnie nad czymś takim myślałem, pozostaje tylko sprawdzić czy rodzic nie posiada takiego id, nad czym się muszę zastanowić (na razie nie wiem za bardzo jak) ;] ale to chyba nie jest skomplikowane?

0

Wystarczyć sprawdzić, czy GetDlgItem zwróci jakiś uchwyt.

0

Wpiąć się w pętlę komunikatów to znaczy tutaj:

void CmxTrackeditorOcxDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_TRACKNAME, edTrackName);
       ......
}

Tak się jeszcze zastanawiam, czy zamiast tworzyć kontrolki za każdym razem dynamicaznie, czy nie było by lepiej ich chować i pokazywać? Ok, zrobiłem już tak, że chowam je i pokazuję, jednak mam błąd makra assert ;/
w klasie CmxTrackeditorOcxDlg mam np CMyEdit ed[5]; i jak rejestruje np tak:

DDX_Control(pDX, 9699, ed[0]);

9699 to losowe id poki co...

HWND CDataExchange::PrepareCtrl(int nIDC)
{
	ASSERT(nIDC != 0);
	ASSERT(nIDC != -1); // not allowed
	HWND hWndCtrl;
   COleControlSite* pSite = NULL;
	m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
	if (hWndCtrl == NULL)
	{
	  // Could be a windowless OCX
	  pSite = m_pDlgWnd->GetOleControlSite(nIDC);
	  if (pSite == NULL)
	  {
		   TRACE(traceAppMsg, 0, "Error: no data exchange control with ID 0x%04X.\n", nIDC);
		   ASSERT(FALSE);   //dokladnie tutaj ;/
		   AfxThrowNotSupportedException();
	  }
	}
	m_idLastControl = nIDC;
	m_bEditLastControl = FALSE; // not an edit item by default

   return hWndCtrl;
}

Czy moze byc to spowodowane tym ze nie zostalo dla niej jeszcze wywolana metoda Create? Ale z drugiej strony jak nie mam tablicy kontrolek tylko pojedyncza to wszystko jest ok ;/

Wymyśliłem rozwiązanie tego, tj będę wywoływać metodę Create w DoDataExchange zamiast w OnInitDialog, ale czy to dobry sposób?

0

Jakie windowless OCX [???] Po co to sprawdzasz, skoro pula numerów ID dla dynamicznych kontrolek ma być zastrzeżona ? I co w ogóle ma robić PrepareCtrl ? Jakoś nie widzę większego sensu w tej metodzie.

ASSERT(nIDC != 0);
ASSERT(nIDC != -1); // not allowed
A to po co ?

Zrób coś na kształ tego:

#define IDC_DYNAMIC_MIN 5000
#define IDC_DYNAMIC_MAX 9999
static int dynamicId = IDC_DYNAMIC_MIN;

int CDataExchange::PrepareNewChildId()
{
   do if(++dynamicId > IDC_DYNAMIC_MAX) dynamicId = IDC_DYNAMIC_MIN; 
   while(m_pDlgWnd->GetDlgItem(dynamicId) != NULL);
   return dynamicId;
}
0

CDataExchange::PrepareCtrl(int nIDC)
To nie jest żadna moja funkcja, to jest funkcja z jakiegoś pliku afx???.cpp z , gdzie mi wskakiwalo z makra assert, o czym ty mowisz jakie windowless ocx?

0

No to pokaż SWÓJ kod.

0

Teraz niestety nie mam do niego dostępu, ale widzę że wyedytowałeś posta, taka funkcja jak tam napisałeś przyda mi się w sumie ;]

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