COM/COM+ Zákl. Inprocess Komponenta a Klient, který ji používá. – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

COM/COM+ Zákl. Inprocess Komponenta a Klient, který ji používá. – C / C++ – Fórum – Programujte.comCOM/COM+ Zákl. Inprocess Komponenta a Klient, který ji používá. – C / C++ – Fórum – Programujte.com

 

vit24
~ Anonymní uživatel
7 příspěvků
20. 12. 2014   #1
-
0
-

Znáte knihu Dalibor Kačmář - Programujeme COM - COM+ ? Hned první projekt mně nefunguje. Jde o komponentu inprocess (DLL) která impl. generator náhodných čísel a klient , kterej jí pak používá. Podařilo se to někomu rozchodit? Já bych potřeboval, kdyby jste to někdo mohl dát do .raru, a upnout někam na uložto atp. Nemusí to bejt přesně z týhle knihy, ale klidně něco jinýho podobně "základního". Tady sem alespoň upnul to co mně nejde k nakouknutí http://uloz.to/x4UtssEG/komponenta-com-zdroj-kod-rar . Je tam i típnutej obr. z registru, jak sem to měl zareg. A buď jestli mně ste schopnej někdo říct co je tam špatně, nebo ideálně poslat nějakej váš starší projekt podobnýho typu, kterej ale funguje. Dík.

Nahlásit jako SPAM
IP: 213.220.195.–
liborb
~ Redaktor
+18
Guru
29. 12. 2014   #2
-
0
-

Jestli si ti podařilo komponentu zaregistrovat, tak ti tedy nešla klientská strana (klient2.cpp). Co ti přesně nešlo? Vyhodilo to nějakou chybu (HRESULT)? Pokud ano, tak ji sem dej a případně i celý projekt.

Nahlásit jako SPAM
IP: 188.75.135.–
vit24
~ Anonymní uživatel
7 příspěvků
30. 12. 2014   #3
-
0
-

Pro liborb: ten projekt jsem upnul na ulozto odkaz je uvedenej v prvním příspěvku!

Včera se mně podařilo najít kód kterej funguje(sou tam i části v POWERBasicu, těch jsem si nevšímal). Tady jsou stránky: http://www.jose.it-berater.org/smfforum/index.php?topic=2980.0 .

Ještě sem neměl čas, ale pokusim se porovnat proč ty zdrojovy soub. z těch stránek výše fungují a ty moje původní ne. Když na něco smysluplnýho přijdu tak sem napíšu.

Nahlásit jako SPAM
IP: 213.220.195.–
vit24
~ Anonymní uživatel
7 příspěvků
4. 1. 2015   #4
-
0
-

Takze problem byl - protoze já sem si tam teda taky dost hral s těma STDAPI a HRESULT __stdcall, ale nakonec to vypada, ze tam muzou bejt oba tvary - asi nejspis jen v tom, ze jsem nemel nastavenou cestu(plnou) k Definicnimu soub. DLL knihovny (.def). Ja to komp. ve VS 2003.net a tam je potřeba nastavit ve vlastnostech DLL soub. (v Solution Exploreru RMB na soub. pak Properties) plnou cestu k tomu .def. Když to neudelate tak se ty funkce na samoregistraci a vytvoreni instance tr. komp. nevyexportujou spravne.

V Dependency Walkeru pak je ve sloupci PI "C"v cervenym ramecku u funkce kterou nejakej soub., importuje(asi ji teda vola) a ocekava ze nas soub. ji spravne exportuje. A kdyz ne, tak v pripade spatne vyexport. reg. fci. neproběhne registrace( tu muzete udelat i rucne jako ja na zacatku), ale inst.tr.komp. stejne nevytvoříte.

Po zadani cesty k tomu souboru to zaclo fungovat. Část bez samoreg. jsem pouzil z Kačmáře a tu registracni část (nemel sem CD ke knize kde je prej prilozena) jsem do projektu pridal podle navodu z toho Jose Rocca Software (to zni jak nejaky porno stranky:-), odkaz je v mem prispevku vyse.

Jinak ten Kačmář me namich protože o vytvareni .def souboru mluvi na str. 70 a 76, ale nezminuje, ze se musí ve vyvoj. prostředí nastavit cesta k souboru. Jak sem to mel sakra vedet?

Az se dostanu k tem zdrojovejm soub.(mam je na jinym kompu), tak je sem třeba hodim. Čus.

Nahlásit jako SPAM
IP: 213.220.195.–
vit24
~ Anonymní uživatel
7 příspěvků
5. 1. 2015   #5
-
0
-

Funkcni kod i s samoregistraci je zde: http://uloz.to/xxqxNixF/1-2-8-1-komponenta-v-jazyce-c-rar .

A dal sem ho i sem. Nejdriv kod komponenty:

generator.idl :

import "unknwn.idl"; 
[ object, uuid(12345678-0000-0000-0000-000000000001)]
interface IGenerator : IUnknown 
{
	HRESULT Reset(); 
	HRESULT NastavMeze([in] float dolni, [in] float horni); 
	HRESULT DejCislo([out, retval] float* cislo); 
}

generator.def :

LIBRARY			Generator.dll
EXPORTS 
				DllGetClassObject   PRIVATE
				DllCanUnloadNow     PRIVATE
				DllRegisterServer   PRIVATE
				DllUnregisterServer PRIVATE
				DllInstall			PRIVATE

Registry.h :

#ifndef _REGISTRY_H_
#define _REGISTRY_H_

#pragma warning (disable: 4267)
//#include <basetyps.h>   // pro pouziti STDAPI misto HRESULT __stdcall

HRESULT RegisterServer(HMODULE hModule, const CLSID& clsid, const char* szFriendlyName, 
					   const char* szVerIndProgID, const char* szProgID);

HRESULT UnregisterServer(const CLSID& clsid, const char* szVerIndProgID, 
						 const char* szProgID);

HRESULT __stdcall DllRegisterServer();
HRESULT __stdcall DllUnregisterServer();

#endif

Registry.cpp:

// Registry.cpp
#include <objbase.h>
#include "Registry.h"

const int CLSID_STRING_SIZE = 39;

BOOL setKeyAndValue(const char* szKey, const char* szSubkey, const char* szValue)
{
 char szKeyBuf[1024];
 long lResult;
 HKEY hKey;
  
 strcpy(szKeyBuf,szKey);   //Copy keyname into buffer.
 if(szSubkey!=NULL)        // Add subkey name to buffer.
 {
     strcat(szKeyBuf, "\\") ;
     strcat(szKeyBuf, szSubkey ) ;
 }
 //Create and open key and subkey.
 lResult=RegCreateKeyEx(HKEY_CLASSES_ROOT,szKeyBuf,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL);
 if(lResult!=ERROR_SUCCESS)
    return FALSE ;
 if(szValue!=NULL)         //Set the Value.
    RegSetValueEx(hKey,NULL,0,REG_SZ,(BYTE*)szValue,strlen(szValue)+1);
 RegCloseKey(hKey);
 
 return TRUE ;
}

void CLSIDtochar(const CLSID& clsid, char* szCLSID, int length)    // Convert a CLSID to a char string.
{
 LPOLESTR wszCLSID=NULL;
 HRESULT hr;

 hr=StringFromCLSID(clsid,&wszCLSID);    // Get CLSID
 if(SUCCEEDED(hr))
 {
    wcstombs(szCLSID, wszCLSID,length);  // Covert from wide characters to non-wide.
    CoTaskMemFree(wszCLSID);             // Free memory.
 }
}


LONG recursiveDeleteKey(HKEY hKeyParent, const char* lpszKeyChild)       // Key to delete
{
 char szBuffer[256];
 DWORD dwSize=256 ;
 HKEY hKeyChild;
 FILETIME time;
 LONG lRes;

 lRes=RegOpenKeyEx(hKeyParent,lpszKeyChild,0,KEY_ALL_ACCESS,&hKeyChild); //Open the child.
 if(lRes!=ERROR_SUCCESS)
    return lRes;
 while(RegEnumKeyEx(hKeyChild,0,szBuffer,&dwSize,NULL,NULL,NULL,&time)==S_OK) //Enumerate all of the decendents of this child.
 {
  lRes=recursiveDeleteKey(hKeyChild,szBuffer);  //Delete the decendents of this child.
  if(lRes!=ERROR_SUCCESS)
  {
     RegCloseKey(hKeyChild);  //Cleanup before exiting.
     return lRes;
  }
  dwSize=256;
 }
 RegCloseKey(hKeyChild);      // Close the child.

 return RegDeleteKey(hKeyParent,lpszKeyChild);  //Delete this child.
}


HRESULT RegisterServer(HMODULE hModule,const CLSID& clsid,const char* szFriendlyName,const char* szVerIndProgID,const char* szProgID)
{
 char szCLSID[CLSID_STRING_SIZE];
 char szModule[512];
 char szKey[64];
  
 if(GetModuleFileName(hModule,szModule,sizeof(szModule)/sizeof(char)))
 {
    CLSIDtochar(clsid, szCLSID,sizeof(szCLSID));                     //Get server location &Convert the CLSID into a char.
    strcpy(szKey, "CLSID\\");                                        //Build the key CLSID\\{...}
    strcat(szKey,szCLSID);
    setKeyAndValue(szKey,NULL,szFriendlyName);                       //Add the CLSID to the registry.
    setKeyAndValue(szKey, "InprocServer32", szModule);               //Add the server filename subkey under the CLSID key.
    setKeyAndValue(szKey, "ProgID", szProgID);                       //Add the ProgID subkey under the CLSID key.
    setKeyAndValue(szKey,"VersionIndependentProgID",szVerIndProgID); //Add the version-independent ProgID subkey under CLSID key.
    setKeyAndValue(szVerIndProgID, NULL, szFriendlyName);            //Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
    setKeyAndValue(szVerIndProgID, "CLSID", szCLSID);
    setKeyAndValue(szVerIndProgID, "CurVer", szProgID);
    setKeyAndValue(szProgID, NULL, szFriendlyName) ;                 //Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
    setKeyAndValue(szProgID, "CLSID", szCLSID) ;
 }
 else
    return E_FAIL;
 
 return S_OK ;
}


HRESULT UnregisterServer(const CLSID& clsid, const char* szVerIndProgID, const char* szProgID)
{
 char szCLSID[CLSID_STRING_SIZE];
 char szKey[64];
 LONG lResult;
  
 CLSIDtochar(clsid, szCLSID, sizeof(szCLSID));                     //Convert the CLSID into a char.
 strcpy(szKey, "CLSID\\");                                         //Build the key CLSID\\{...}
 strcat(szKey, szCLSID) ;
 lResult=recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);             //Delete the CLSID Key - CLSID\{...}
 lResult=recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);    //Delete the version-independent ProgID Key.
 lResult=recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;         //Delete the ProgID key.
  
 return S_OK ;
}
//End Registry.cpp

generator.cpp :

///////////////////////////////////////////////////////////////p
// In-process komponenta generátoru náhodných cisel. 
// Soubor:  generátor.cpp 
//
// Autor:  Dalibor  Kacmar 
// 
// (C)   2000 
///////////////////////////////////////////////////////////////

#include "generator_h.h" // Vygenerovano kompilatorem MIDL
#include <stdlib.h>		// Pro praci s srand() a rand()
#include <time.h>		// Pro praci s time()
#include <iostream>	// Pro praci s vystupnim proudem cout
#include "Registry.h"
// Globals
HINSTANCE  g_hModule           = NULL;              //Store dll instance handle
const char g_szFriendlyName[]  = "Generator";   //Store friendly name of component
const char g_szVerIndProgID[]  = "Gen.Generator";    //Store Version Independent ProgID
const char g_szProgID[]        = "Gen.Generator.1";  //Store Versioned Program ID.
long g_cLocks = 0;		// pocitadlo pro uzamceni komponenty v pameti

// CLASS ID komp. {12345678-0000-0000-0000-000000000002}
const CLSID CLSID_Generator = {0x12345678,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}};
// Prototypy
HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv);
HRESULT __stdcall DllCanUnloadNow(); 
HRESULT __stdcall DllInstall(char* s);

class CGenerator : public IGenerator
{
public :
	// Metody rozhrani IUnknown
	ULONG __stdcall AddRef();
	ULONG __stdcall Release();
	HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);

	// Metody rozhrani IGenerator
	HRESULT __stdcall Reset();
	HRESULT __stdcall NastavMeze(float dolni, float horni);
	HRESULT __stdcall DejCislo(float * cislo);

	CGenerator() : m_cRef(1), m_fDolni(0), m_fHorni(1)
	{
		g_cLocks++;			// pocitadlo instanci komponenty
		Reset();
	}
	~CGenerator() { g_cLocks--; }

private:
	ULONG m_cRef;	// pocitadlo referenci na konkretni instanci
	float m_fDolni, m_fHorni;	// horni a dolni mez generovanych cisel
};

// Metoda  inkrementuje  počitadlo  referenci 
ULONG CGenerator::AddRef() 
{ 
	return ++m_cRef; 
}

// Metoda  dekrementuje  počitadlo  ref. a připadne  uvolňuje  instanci z paměti
ULONG CGenerator::Release() 
{
	if (--m_cRef != 0)   //  Je  to jiz poslední instance? 
		return  m_cRef;    //  Jeste ne 
	delete this;  //  Nikdo  jiný  tuto  instanci  neuvolní  ->  SAMODESTRUKCE 
	return 0; 
}

//  Metoda zjistuje existenci požadovaného rozhráni na zaklade IID a vraci na 
// nej ukazatel 
HRESULT CGenerator::QueryInterface(REFIID riid,  void** ppv) 
{
	if ( riid == IID_IUnknown)  // Implementujeme jen IUnknown 
		*ppv  =  (IUnknown*)this; 
	else  if ( riid == IID_IGenerator)  // nebo IGenerator 
		*ppv = (IGenerator*)this; 
	else 
	{
		*ppv  = NULL; 
		return  E_NOINTERFACE;  //  Konstanta signálizujici neexistujici rozhráni 
	}
	AddRef(); 
	return  S_OK;
}

//  Metoda  nastaví horni a dolni  nterval, z nehoz budou cisla  generovaná 
HRESULT CGenerator::NastavMeze(float dolni, float horni) 
{ 
	m_fDolni = dolni ; 
	m_fHorni = horni; 
	return  S_OK;
}
// Metoda  inicializuje generátor náhodných cisel 
HRESULT CGenerator::Reset() 
{
	srand((unsigned)time(NULL));
	return  S_OK; 
}
//  Metoda generuje další náhodné cislo v určeném rozsahu 
HRESULT CGenerator::DejCislo(float * cislo) 
{
	*cislo = rand()/(float)RAND_MAX*(m_fHorni - m_fDolni)+ m_fDolni; 
	return  S_OK; 
}

// Class Factory pro konstrukci instanci tridy CGenerator 
class CGeneratorFactory  : public  IClassFactory 
{ 
public: 
//  IUnknown 
ULONG  __stdcall AddRef();
ULONG  __stdcall  Release();
HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
// IClassFactory 
HRESULT  __stdcall CreateInstance(IUnknown *pUnknownOuter, 
	REFIID  riid,  void** ppv); 
HRESULT  __stdcall LockServer(BOOL bLock);

CGeneratorFactory() : m_cRef(1) { g_cLocks++; } 
~CGeneratorFactory()  { g_cLocks--; } 

private: 
	ULONG m_cRef; 
};

ULONG CGeneratorFactory::AddRef() 
{
	return  ++m_cRef; 
}

ULONG CGeneratorFactory::Release() 
{ 
	if (--m_cRef != 0) 
		return m_cRef; 
	delete this; 
	return 0; 
}

HRESULT CGeneratorFactory::QueryInterface(REFIID riid , void** ppv) 
{
	// Podporujeme pouze IUnknown 
	if (riid == IID_IUnknown) 
		*ppv = (IUnknown*) this; 
	// a IClassFactory 
	else if (riid == IID_IClassFactory) 
		*ppv = (IClassFactory*)this; 
	// jiné ne! 
	else
	{
		*ppv = NULL; 
		return E_NOINTERFACE; 
	} 
	AddRef(); 
	return S_OK;
}

// Metoda slouzi pro zakládáni instaci tridy CGenerator, tedy instanci 
// našeho COM objektu. 
HRESULT CGeneratorFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv) 
{
	// Zatim nepodporujeme  agregaci 
	if(pUnknownOuter != NULL) 
		return  CLASS_E_NOAGGREGATION; 
	// Novy  objekt 
	CGenerator *pGenerator = new CGenerator;
	if (pGenerator == NULL) 
		return  E_OUTOFMEMORY; 
	// Jeste ziskat ukazatel na požadované rozhraní 
	HRESULT hr = pGenerator->QueryInterface(riid, ppv); 
	pGenerator->Release(); 
	return hr;
}

// Funkce uzamyká nebo odemyká server v paměti. Pozor inkrementálně! 
HRESULT CGeneratorFactory::LockServer(BOOL bLock) 
{
	if (bLock) 
		g_cLocks++; 
	else 
		g_cLocks--; 
	return S_OK; 
}
// Funkce zjistuje, zda je server mozne odstraniz z paměti. 
HRESULT __stdcall DllCanUnloadNow() 
{
	if(g_cLocks == 0) 
		return S_OK; 
	else
		return S_FALSE; 
};

// Funkce zakládá instanci požadované Class Factory a vraci ukazatel na 
// jeji rozhráni IClassFactory. 
HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv) 
{
	// Kontrola na požadovanou Class Factory.
	// Jinou nez pro CLSID_Generator  tato  komponenta  neposkytuje! 
	if (clsid  != CLSID_Generator) 
		return CLASS_E_CLASSNOTAVAILABLE; 
	// Nova instance Class factory 
	CGeneratorFactory* pFactory = new CGeneratorFactory; 
	if (pFactory == NULL) 
		return  E_OUTOFMEMORY; 
	// riid je pravděpodobné IID_IClassFactory. 
	HRESULT hr = pFactory->QueryInterface(riid, ppv); 
	pFactory->Release(); 
	return hr; 
};

HRESULT __stdcall DllRegisterServer()           //created - which creation causes memory allocations for
{                                    //both the class's VTable pointers and the VTables
 return RegisterServer               //themselves.  Further, class CA implements the abstract
 (                                   //base classes I_X and I_Y, and pointers to the  
  g_hModule,                         //implementations of the pure virtual functions contained
  CLSID_Generator,                          //within these base classes are placed in the respective 
  g_szFriendlyName,                  //VTable of each interface.  At this point we have an   
  g_szVerIndProgID,                  //object in memory which can be called to do work for us.
  g_szProgID
 );                                  //DllRegisterServer() and DllUnregisterServer are for
}                                    //adding or eliminating class ids, program ids, etc.,...


HRESULT __stdcall DllUnregisterServer()         //relating to the component from the registry.  They are
{                                    //called by the RegSvr32.exe Windows component.  For
 return UnregisterServer             //example, on this development machine CA.dll is in
 (                                   //C:\Code\VStudio\VC++6\Projects\COM\ComObjects\CA\Release\CA.dll
  CLSID_Generator,                          //I'd register it by doing this...
  g_szVerIndProgID, 
  g_szProgID                         //RegSvr32 C:\Code\VStudio\VC++6\Projects\COM\ComObjects\CA\Release\CA.dll
 );
}                                    //Having done that I thankfully saw a message box telling...

HRESULT __stdcall DllInstall(char* s) {
  return  S_OK;
};
// VSTUPNI BOD DO DLL
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
	switch (reason)                     //me registration was successful.  Registry code is pretty 
	{                                   //horrible and in this code was relegated to Registry.cpp
	case DLL_PROCESS_ATTACH:           //Note that that code needs the dll's instance handle
		g_hModule=hInst;                 //and that is saved just at left in DllMain in a global
		break;                           //variable just for that purpose.
	case DLL_PROCESS_DETACH:
		break;
	}

	return TRUE;                        //Returning FALSE cause
}
// End generator.cpp

Nahlásit jako SPAM
IP: 213.220.195.–
vit24
~ Anonymní uživatel
7 příspěvků
5. 1. 2015   #6
-
0
-

A nasleduje kod klienta. Jinak ke klientovi i k budouci DLL si musite ještě pripnout nektery soubory co generuje MIDL z IDL souboru. Na to uz kazdej pride a ja to z hlavy stejne nevim.

klient2.cpp :

#define _WIN32_DCOM 
#include  <iostream> 
#include "stdio.h"
using namespace std;
#include "generator_h.h" // Generován  překladačem  MIDL 
#include "generator_i.c"

void ErrorDescription(HRESULT hr); 

// {12345678-0000-0000-0000-000000000002}
const  CLSID CLSID_Generator =  {0x12345678,0x0000,0x0000, 
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}};

void main()
{
	IClassFactory * pIFactory = NULL;
	IGenerator * pGen = NULL; 

	HRESULT hr = CoInitialize(NULL); 
	if (FAILED(hr)) 
		cout << "Nelze inicializovat apartment." << endl; 
	
	hr = CoGetClassObject(CLSID_Generator, CLSCTX_INPROC_SERVER, NULL,
		IID_IClassFactory, (void**)&pIFactory);
	
	if (FAILED(hr)) 
		cout << "Nelze zalozit Class Factory komponenty." << endl;
	
	ErrorDescription(hr);
	
	if (SUCCEEDED(hr))
	{
		hr = pIFactory->CreateInstance(NULL, IID_IGenerator, (void**)&pGen);
		pIFactory->Release();
	
		if (FAILED(hr))
			cout << "Nelze vytvorit instanci komponenty tridy Generator." << endl;
		
		if (SUCCEEDED(hr))
		{	
			float cislo;
			hr = pGen->NastavMeze(-100, 100); 
				if (SUCCEEDED(hr)) 
					cout << "Nastaveny meze generatoru na <-100,100>" << endl; 
				cout << "Generuji 10 cisel: " << endl; 
				for (int i = 0; i < 10; i++) 
				{
					hr = pGen->DejCislo(&cislo); 
					if(SUCCEEDED(hr))
						cout << cislo << endl;
				}
			pGen->Release(); 	
		}
	}
	CoUninitialize();
	int n; cin >> n;
}

void ErrorDescription(HRESULT hr) 
{
	if(FACILITY_WINDOWS == HRESULT_FACILITY(hr))
        hr = HRESULT_CODE(hr);
    char* szErrMsg;
    if(FormatMessage(
	  FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 
      NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
      (LPTSTR)&szErrMsg, 0, NULL) != 0) 
	{
        printf("%s", szErrMsg);
        LocalFree(szErrMsg);
    } 
	else
        printf("[Could not find a description for error # %#x.]\n", hr);
}
	

	

Ty funkce ErrorDescription() si nemusíte všímat, ja ji pouzival když to nefungovalo. Zdar!

Nahlásit jako SPAM
IP: 213.220.195.–
vit24
~ Anonymní uživatel
7 příspěvků
7. 1. 2015   #7
-
0
-

#4 vit24

Jeste jsem zapomel to nejdulezitejsi ta cesta kam v Properties zadate tu cestu k .def souboru je : \Configuration Properties \Linker \Input \Module Definition File

Nahlásit jako SPAM
IP: 213.220.195.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 26 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý