- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
bool getSelectedFile(wchar_t *out, bool skip) {
	HWND hwndFind = GetForegroundWindow();
	TCHAR g_szPath[BUF_SIZE];
	TCHAR g_szItem[BUF_SIZE];
	//g_szPath[0] = TEXT('\0');
	//g_szItem[0] = TEXT('\0');
	memset(g_szPath, 0, sizeof(TCHAR) * BUF_SIZE);
	memset(g_szItem, 0, sizeof(TCHAR) * BUF_SIZE);
	IShellWindows *psw;
	if(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw) != S_OK) return false;
	
	VARIANT v;
	v.vt = VT_I4;
	IDispatch  *pdisp;
	bool fFound = false;
	bool pExtracted = false;
	bool nExtracted = false;
	
	for (V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) {
			IWebBrowserApp *pwba;
			if(SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) {
				HWND hwndWBA;
				if (SUCCEEDED(pwba->get_HWND((LONG_PTR*)&hwndWBA)) && hwndWBA == hwndFind) {
					fFound = true;
					IServiceProvider *psp;
					if(SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) {
						IShellBrowser *psb;
						if(SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&psb))) {
							IShellView *psv;
							if(SUCCEEDED(psb->QueryActiveShellView(&psv))) {
								IFolderView *pfv;
								if(SUCCEEDED(psv->QueryInterface(IID_IFolderView, (void**)&pfv))) {
									IPersistFolder2 *ppf2;
									if(SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, (void**)&ppf2))) {
										LPITEMIDLIST pidlFolder;
										if(SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) {
											if(SHGetPathFromIDList(pidlFolder, g_szPath)) {
												pExtracted = true;
												if(skip) {
													lstrcpy(out, g_szPath);
													out[lstrlen(g_szPath)] = 0;
													return true;
												}
											}
											int iFocus;
											if(SUCCEEDED(pfv->GetFocusedItem(&iFocus))) {
												LPITEMIDLIST pidlItem;
												if (SUCCEEDED(pfv->Item(iFocus, &pidlItem))) {
													IShellFolder *psf;
													if (SUCCEEDED(ppf2->QueryInterface(IID_IShellFolder, (void**)&psf))) {
														STRRET str;
														if(SUCCEEDED(psf->GetDisplayNameOf(pidlItem, SHGDN_INFOLDER, &str))) {
															StrRetToBuf(&str, pidlItem, g_szItem, 1024);
															nExtracted = true;
															int psz = lstrlen(g_szPath);
															int isz = lstrlen(g_szItem);
															if(pExtracted) {
																lstrcpy(out, g_szPath);
																out[psz] = '\\';
															}
															lstrcpy(out+psz+1, g_szItem);
															out[psz + isz + 2] = 0;
														}
														psf->Release();
													}
													CoTaskMemFree(pidlItem);
												}
											}
											CoTaskMemFree(pidlFolder);
										}
										ppf2->Release();
									}
									pfv->Release();
								}
								psv->Release();
							}
							psb->Release();
						}
						psp->Release();
					}
				}
				pwba->Release();
			}
			pdisp->Release();
	}
	psw->Release();
	return (pExtracted && nExtracted);
}
                                 
        
            Две очаровательных (говно) лестницы из какой-то очередной переназначалки горячих клавиш в Windows.
Оригинал тут: https://github.com/mapseamoff/KeyBinder/blob/master/ShellHelper/ShellHelper/main.cpp
        
        
http://ideone.com/SuLk5o
PS: Обновил, дефекейстра снизу лучше высрал с do while
http://ideone.com/52YbOs
А в эту кашудумать даже не хочется.
Я бы так сделал.
в сишке switch (errlevel) мне нравится гораздо больше goto
Но, если не сложно, то и то и другое давай.
для COM, в принципе, уже есть библиотечный CComPtr в сраном ATL, который сделает Release в деструкторе
на сишке - все варианты сводятся к тому, что надо проэмулировать try { ... } finally, это делается либо через goto (я не сторонник этого способа), либо через do { ... } while (0); с бряками
конкретно пример выше со сферическими initXXX() можно было бы сделать вот так:
чтобы человек изначально приучался к хорошему и понятному
там вечно какой-то пиздей творится
а потом дескрипторы освобождать
ничего лучше я не видел
Я вот так делал:
1) сначала в переменные ложим NULL/INVALID_HANDLE_VALUE.
2) goto cleanup при любой ошибке
3) На cleanup: проверяем переменные на пустоту и вызываем соотв. функции для освобождения
Тут этот самый do { ... } while (false) с бряками, имхо, ничуть не структурней чем одинокая метка и прыжки вперед.
1) эмуляция try ... finally
2) бряк из 2-3 вложенных циклов (все лучше чем флагоёбство)
3) хардкорный конченный автомат (читается легче чем свич и переменная со стейтом)
Барсик закаляет
А еще можно было писать GOTO N*10 + 100 ;)
Ну, как вариант, можно превратить код в вермишель, засунув туда GOTO на свободное место ;)
Или подвинуть пару соседних команд чуть подальше:Как видим - пришлось поменять номер только в одной строке.
с точки зрения говноэмуляции try {} визуальная вложенность кода в некий блок, за которым угадывается специфичный do {} while (0); неплохо намекает само по себе
а вот goto cleanup; такого профита не имеет
> delete foo;
Ну здрасти.
delete foo; хватит всем достаточно
Круто я слился ;) Хотел написать освобождение какого-нибудь сишного ресурса, а написал бессмысленное и беспощадное крестоблядство. Вот к чему приводит спешка.
if (pwba) pwba->Release();
все мы не без греха, да, LispGovno? :)
http://ideone.com/dhg9nz
http://ideone.com/h6S0k0
http://ideone.com/5vHOqv
Чё это посоны?