|
Fixing missing shortcuts in cmd.exe |
Av: Ove Halseth |
Onsdag 30.05.2012 (11:10) |
I finally got annoyed enough to fix missing ALT-F4 and CTRL-V in command-prompt.
The solution is this AutoHotkey script:
; Language: English
; Platform: Win2k/XP/Vista/2k3 server/2k8 server
; Author: Ove Halseth <ove@wis.no>
#IfWinActive ahk_class ConsoleWindowClass
!F4:: Send !{SPACE}C
^V:: Send !{SPACE}EP
return
Ove B-) |
|
--Emner: Operativsystem, Utvikling, Windows
|
|
|
Redirect dll using manifests |
Av: Ove Halseth |
Onsdag 30.05.2012 (10:19) |
To break free from dll-hell you can use manifests to spesify that your application should use local dll's instead of system dll's.
As an added bonus you will not have to register the dll's with regsvr32 in order to use them. Nice if end user is not local admin.
In order to redirect exe to use local dll's all you need is a manifest file pr dll and a corresponding manifest file for the exe.
You could compile the exe-manifest file into the exe, but it's not required.
The most tricky part is to get the dll-manifest and the exe-manifest to work together.
Create dll-manifests
I'll recomend generating the dll-manifests using microsofts mt.exe (on Win2k8 R2 i found it in C:\Program Files\Microsoft\SDKs\Windows\v6.1\Bin\mt.exe)
The command line for generating dll-manifest is: mt.exe -tlb:example.dll -dll:example.dll -out:example.dll.manifest
Open the generated manifest file and clean it up by adding linebreak and indention.
For our use we had no use of the comInterfaceExternalProxyStub, so I deleted those entries. But leaving them in would do no harm I guess.
Create exe-manifest
Best illustrated with an example.
Here is our manifest for an app named Navi.exe that uses three dll's:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Navi.exe" version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="ChilkatRsa.dll" version="9.3.1.0"/>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="ChilkatCrypt2.dll" version="9.3.0.0"/>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="ChilkatCert.dll" version="9.3.0.0"/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</assembly>
You will need to replace application/dll name and version.
The last section: compability says that our application is compatible with Vista and Win7
To run your application using local dll's, the exe, dll's and it's corresponding manifests needs to be in the same folder.
If you are writing your application in delphi you could add the exe-manifest in the exe by creating a resource file: appname.RC
With the following line: 1 24 "appname.exe.manifest"
And then compile the RC: brcc32 appname.RC
You should then have a appname.RES that you would have to include in your project. I guess you already have a "{$R *.res}" line in your dpr-file. If so it would be included in your exe, the next time you compile your project.
I sometimes get conflict with the apps icon that delphi tries to put in the same res-file. So if your app is missing the icon after adding the manifest. Try adding it to the project again, I have not found out when it gives me a conflict and when it doesn't...
Ove B-) |
|
--Emner: Delphi, Utvikling
|
|
|
Laste ned passordbeskyttet fil med VBA |
Av: Ove Halseth |
Fredag 11.05.2012 (14:44) |
Fant fort ut at en kunne laste ned vanlig fil med denne koden fra www.cpearson.com
Option Explicit
Option Compare Text
Public Enum DownloadFileDisposition
OverwriteKill = 0
OverwriteRecycle = 1
DoNotOverwrite = 2
PromptUser = 3
End Enum
Private Declare Function SHFileOperation Lib "shell32.dll" Alias _
"SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long
Private Declare Function PathIsNetworkPath Lib "shlwapi.dll" _
Alias "PathIsNetworkPathA" ( _
ByVal pszPath As String) As Long
Private Declare Function GetSystemDirectory Lib "kernel32" _
Alias "GetSystemDirectoryA" ( _
ByVal lpBuffer As String, _
ByVal nSize As Long) As Long
Private Declare Function SHEmptyRecycleBin _
Lib "shell32" Alias "SHEmptyRecycleBinA" _
(ByVal hwnd As Long, _
ByVal pszRootPath As String, _
ByVal dwFlags As Long) As Long
Private Const FO_DELETE = &H3
Private Const FOF_ALLOWUNDO = &H40
Private Const FOF_NOCONFIRMATION = &H10
Private Const MAX_PATH As Long = 260
Private Type SHFILEOPSTRUCT
hwnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAnyOperationsAborted As Boolean
hNameMappings As Long
lpszProgressTitle As String
End Type
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" ( _
ByVal pCaller As Long, _
ByVal szURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As Long, _
ByVal lpfnCB As Long) As Long
Public Function DownloadFile(UrlFileName As String, _
DestinationFileName As String, _
Overwrite As DownloadFileDisposition, _
ErrorText As String) As Boolean
Dim Disp As DownloadFileDisposition
Dim Res As VbMsgBoxResult
Dim B As Boolean
Dim S As String
Dim L As Long
ErrorText = vbNullString
If Dir(DestinationFileName, vbNormal) <> vbNullString Then
Select Case Overwrite
Case OverwriteKill
On Error Resume Next
Err.Clear
Kill DestinationFileName
If Err.Number <> 0 Then
ErrorText = "Error Kill'ing file '" & DestinationFileName & "'." & vbCrLf & Err.Description
DownloadFile = False
Exit Function
End If
Case OverwriteRecycle
On Error Resume Next
Err.Clear
B = RecycleFileOrFolder(DestinationFileName)
If B = False Then
ErrorText = "Error Recycle'ing file '" & DestinationFileName & "." & vbCrLf & Err.Description
DownloadFile = False
Exit Function
End If
Case DoNotOverwrite
DownloadFile = False
ErrorText = "File '" & DestinationFileName & "' exists and disposition is set to DoNotOverwrite."
Exit Function
'Case PromptUser
Case Else
S = "The destination file '" & DestinationFileName & "' already exists." & vbCrLf & _
"Do you want to overwrite the existing file?"
Res = MsgBox(S, vbYesNo, "Download File")
If Res = vbNo Then
ErrorText = "User selected not to overwrite existing file."
DownloadFile = False
Exit Function
End If
B = RecycleFileOrFolder(DestinationFileName)
If B = False Then
ErrorText = "Error Recycle'ing file '" & DestinationFileName & "." & vbCrLf & Err.Description
DownloadFile = False
Exit Function
End If
End Select
End If
L = URLDownloadToFile(0&, UrlFileName, DestinationFileName, 0&, 0&)
If L = 0 Then
DownloadFile = True
Else
ErrorText = "Buffer length invalid or not enough memory."
DownloadFile = False
End If
End Function
Private Function RecycleFileOrFolder(FileSpec As String) As Boolean
Dim FileOperation As SHFILEOPSTRUCT
Dim lReturn As Long
If (Dir(FileSpec, vbNormal) = vbNullString) And _
(Dir(FileSpec, vbDirectory) = vbNullString) Then
RecycleFileOrFolder = True
Exit Function
End If
With FileOperation
.wFunc = FO_DELETE
.pFrom = FileSpec
.fFlags = FOF_ALLOWUNDO
.fFlags = FOF_ALLOWUNDO + FOF_NOCONFIRMATION
End With
lReturn = SHFileOperation(FileOperation)
If lReturn = 0 Then
RecycleFileOrFolder = True
Else
RecycleFileOrFolder = False
End If
End Function
Men ingen enkel måte og laste ned en passordbeskyttet fil:-(
Løsningen er snublende nær, det er bare og laste ned med url'en: http://brukernavn:passord@site.no
Ove B-) |
|
--Emner: Utvikling, VBA
|
|
|
ExtGWT og RequestFactory integrasjon |
Av: Stig Runar Vangen |
Fredag 04.02.2011 (13:42) |
Sencha har sagt at de for neste versjon av ExtGWT kommer til å nærme seg standardene som Google bruker for GWT. Tidligere har man i ExtGWT måtte gjøre en del spesialtilpasninger for å få dataflyt til å fungere optimalt. Vi har forsøkt å foreberede kodebasen vår i påvente av ExtGWT 3, og en sentral bit her er RequestFactory, som både reduserer mengden data som overføres mellom klient og server, samt gjør at vi ikke trenger å skrive like mye kode for å endre på data. Disse endringene spenner seg over både server og klient side av kodebasen.
Spring og RequestFactory
Bruker foreløpig servlet angitt i web.xml. Denne er uavhengig av hvilken RequestContext du bruker, men hver implementasjon av disse er ikke Spring-kompatible. Derfor står dette som et punkt på listen over ting som må utbedres.
ExtGWT og RequestFactory
Sencha sier selv at main i ExtGWT 3 skal bevege seg mot en bedre integrasjon mot GWT. Dette innebærer å bruke de rammeverk som allerede eksisterer i GWT. Deriblant finner vi RequestFactory (introdusert i GWT 2.1), som er et rammeverk for å minimere trafikk over nettlinjen. Dette gjøres ved å bare sende endringer gjort i modellen i stedet for hele modellen. En grunnleggende introduksjon er tilgjengelig her:
http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html
Det første som slår meg når jeg leser denne dokumentasjonen, er at Google har brutt alle skikker for god programmering når de lagde dette rammeverket. Alle metoder for å hente ut data fra databasen ligger her som statiske metoder på entiteten. Det at disse metodene er statiske stopper for integrasjon mot Spring/Guice eller lignende. Det at de er plassert på entiteten gjør at koden ikke er separert i kodelag som gjør videre utvikling lettere. Dette har blitt gjort litt lettere i GWT 2.1.1, med en god del forbedringer for RequestFactory:
http://code.google.com/p/google-web-toolkit/wiki/RequestFactory_2_1_1
Man kan her dra ut implementasjon av uthenting av data fra entiteter ved hjelp av locators. Disse trenger heller ikke lenger være statiske, noe som letter implementasjon mot Spring ganske mye. Derimot er det veldig lite dokumentasjon tilgjengelig enda. Hverken Google eller bloggere har begynte skrive om det forbedrede rammeverket enda. Det har derfor vært en lang prosess med prøving og feiling for å integrere RequestFactory i vårt system.
RequestFactory GIN provider
-
public class ContactRequestFactoryProvider implements
-
Provider<ContactRequestFactory> {
-
-
@Inject
-
private CoreGinjector coreGinjector;
-
-
@Override
-
public final ContactRequestFactory get() {
-
ContactRequestFactory contactRequestFactory =
-
GWT.create(ContactRequestFactory.class);
-
contactRequestFactory.initialize(coreGinjector.getEventBus(),
-
coreGinjector.getRequestTransport());
-
return contactRequestFactory;
-
}
-
}
For oppretting av RequestFactory-objekter brukes en GIN-provider. Resultatet av denne er igjen bundet inn som en singleton gjennom GIN-konfigurasjonen. Denne initieres ved å bruke vår globale eventbus og en tilpasset transport-metode. Grunnen til at vi trenger en tilpasset transport-metode er at vi henter data fra en annen web-context enn den klienten ligger på.
RequestFactory
-
public interface ContactRequestFactory extends RequestFactory {
-
ContactRequest contactRequest();
-
}
Factory i seg selv henviser bare til en request implementasjon.
Contact request
-
@Service(value = ContactAdapter.class, locator = InstanceServiceLocator.class)
-
public interface ContactRequest extends RequestContext {
-
-
Request<ContactProxy> get(String id);
-
-
Request<Void> persist(ContactProxy contact);
-
-
Request<Void> remove(ContactProxy contact);
-
}
Her defineres de metodene man ønsker å bruke for å kommunisere fra klient til server. Dette er de metodene som er spesifikt for kontakt-modulen. Klassen er i seg selv annotert som en GWT-service, der implementasjonen av disse metodene ligger i ContactAdapter-klassen (trenger ikke lenger være entitets-klassen i GWT 2.1.1), mens ContactLocator (locators er nytt i GWT 2.1.1) tar seg av oppdateringer av entiteter.
Contact RequestFactory adapter
-
@Component
-
public class ContactAdapter {
-
-
private static ContactDao contactDao;
-
-
public ContactAdapter() {
-
}
-
-
@Autowired
-
public ContactAdapter(final ContactDao contactDao) {
-
ContactAdapter.contactDao = contactDao;
-
}
-
-
public final Contact get(final String id) {
-
Scanner scanner = new Scanner(id);
-
scanner.useLocale(Locale.ROOT);
-
if (scanner.hasNextLong()) {
-
return contactDao.get(scanner.nextLong());
-
}
-
return null;
-
}
-
-
public final void persist(final Contact contact) {
-
contactDao.saveOrUpdate(contact);
-
}
-
-
public final void remove(final Contact contact) {
-
contactDao.delete(contact);
-
}
-
}
Her implementeres de metodene som er definert i request-interfacet. Klassen er tagget med @Component slik at Spring finner denne klassen gjennom auto-scanning. Vi slipper dermed spesifikk konfigurasjon per modul. En kontakt-DAO blir gitt fra Spring sin kontekst. Denne lagres som en statisk variabel. Grunnen til dette er at RequestFactory oppretter instanser av dette objektet uavhengig av Spring. Ved oppstart blir DAO overlevert fra Spring, og alle instanser av denne adapteren vil ha tilgang til gjeldende DAO.
Instance ServiceLocator
-
public class InstanceServiceLocator implements ServiceLocator {
-
-
private static final Log LOGGER = LogFactory
-
.getLog(InstanceServiceLocator.class);
-
-
@Override
-
public final Object getInstance(final Class<?> clazz) {
-
try {
-
Object newInstance = clazz.newInstance();
-
return newInstance;
-
} catch (InstantiationException ex) {
-
LOGGER.fatal("Failed to create instance", ex);
-
} catch (IllegalAccessException ex) {
-
LOGGER.fatal("Failed to create instance", ex);
-
}
-
return null;
-
}
-
}
Dette er en veldig enkel ServiceLocator som ganske enkelt oppretter nye instanser av den klassen man etterspør. Det er mulig at vi i senere tid vil trenge å hente ut data fra Spring sin context i stedet for å lage objekter utenfor.
Entity proxy
-
@ProxyFor(value = Contact.class, locator = ContactLocator.class)
-
public interface ContactProxy extends BaseEntityProxy {
-
-
String getAddress();
-
-
String getFirstName();
-
-
String getLastName();
-
-
void setAddress(String address);
-
-
void setFirstName(String firstName);
-
-
void setLastName(String lastName);
-
}
Entitets-proxy-er blir implementert som autobeans på klientsiden. Disse er en speiling av entiteter på server-siden. Man må i proxy angi navn på metoder basert på Java Bean-standarden. Dette vil vanligvis være en speiling av de metode-navnene man finner i entiteten. Dette for at RequestFactory skal kunne hente data entiteten før de dras over til klienten. Dersom disse ikke stemmer overens får man feil ved første forsøk på uthenting av data. Merk også at vi her peker til en locator. Denne er ikke av typen ServiceLocator, som plasseres på en request.
-
@Entity
-
public class Contact extends AbstractDocumentEntity implements Serializable {
-
-
private String firstName;
-
private String lastName;
-
private String address;
-
-
public String getAddress() {
-
return address;
-
}
-
-
public void setAddress(String address) {
-
this.address = address;
-
}
-
-
public String getFirstName() {
-
return firstName;
-
}
-
-
public void setFirstName(String firstName) {
-
this.firstName = firstName;
-
}
-
-
public String getLastName() {
-
return lastName;
-
}
-
-
public void setLastName(String lastName) {
-
this.lastName = lastName;
-
}
-
}
Dette er et forenklet utdrag av entiteten som autobean proxy peker til. Merk at metode-kallene i proxy kaller til feltene i klassen, ikke metodene. Begge klasser følger samme regelsett for navngiving av getters/setters.
Contact RequestFactory locator
-
public abstract class DocumentEntityLocator<T extends AbstractDocumentEntity>
-
extends Locator<T, Long> {
-
-
private static final Log LOGGER = LogFactory.getLog(DocumentEntityLocator.class);
-
-
public DocumentEntityLocator() {
-
}
-
-
public abstract BaseDao<T> getDao();
-
-
@Override
-
public final T create(final Class<? extends T> clazz) {
-
try {
-
Class<? extends T> entityClass = getEntityClass(clazz);
-
if (entityClass != null) {
-
T newInstance = entityClass.newInstance();
-
getDao().saveOrUpdate(newInstance);
-
return newInstance;
-
}
-
} catch (InstantiationException ex) {
-
LOGGER.fatal("Failed to create instance", ex);
-
} catch (IllegalAccessException ex) {
-
LOGGER.fatal("Failed to create instance", ex);
-
}
-
return null;
-
}
-
-
@Override
-
public final T find(final Class<? extends T> clazz, final Long id) {
-
return getDao().get(id);
-
}
-
-
@Override
-
public final Class<T> getDomainType() {
-
return getDao().getDomainType();
-
}
-
-
@Override
-
public final Long getId(final T domainObject) {
-
return domainObject.getId();
-
}
-
-
@Override
-
public final Class<Long> getIdType() {
-
return Long.TYPE;
-
}
-
-
@Override
-
public final Object getVersion(final T domainObject) {
-
return domainObject.getRevisionNumber();
-
}
-
-
@SuppressWarnings("unchecked")
-
private <X extends Object> Class<X> getEntityClass(
-
final Class<? extends Object> clazz) {
-
Entity entity = clazz.getAnnotation(Entity.class);
-
if (entity != null) {
-
return (Class<X>) clazz;
-
}
-
-
Class<?> superclass = clazz.getSuperclass();
-
if (superclass != null) {
-
return getEntityClass(superclass);
-
}
-
-
return null;
-
}
-
}
En locator er bindeledded mellom din modell-struktur og RequestFactory. Her definerer du hvordan man henter ut en entitet fra en id. I tillegg definers hvordan man finner id, versjon og type fra en entitet. DAO hentes her ut gjennom en abstrakt metode.
-
@Component
-
public class ContactLocator extends DocumentEntityLocator<Contact> {
-
-
private static final Log LOGGER = LogFactory.getLog(ContactLocator.class);
-
private static ContactDao contactDao;
-
-
public ContactLocator() {
-
}
-
-
@Autowired
-
public ContactLocator(final ContactDao contactDao) {
-
ContactLocator.contactDao = contactDao;
-
}
-
-
@Override
-
public final BaseDao<Contact> getDao() {
-
return ContactLocator.contactDao;
-
}
-
}
Dette er en implementasjon av en locator for en gitt modul. Denne klassen er annotert med @Component for at Spring skal behandle den ved oppstart. Den statiske kontakt DAO blir da satt. Denne må være statisk da det er RequestFactory som i ettertid vil lage nye instanser av denne, og er som kjent ikke fullstendig Spring-kompatibel. Denne gis så til den abstrakte klassen via implementeringen av DAO-uthenting. Dette gjør det raskt og enkelt å sette opp nye moduler.
Videre plan er å gjøre et forsøk på å utvide RequestFactory på serverside slik at vi ikke er så avhengige av statiske variabler for Spring-Beans. Dette vil gjøre at koden er bedre rustet på endringer i fremtiden.
|
|
--Emner: Java, Utvikling, Web 2.0, WisWeb 2
|
|
|
Spring og GWT-RPC integrasjon |
Av: Stig Runar Vangen |
Torsdag 03.02.2011 (14:23) |
Som en del av implementasjonen av serverbiten av WisWeb 2 har vi gjort en jobb for integrasjon GWT og Spring. I tillegg har det blitt gjort en god del på klientsiden for å integrere RequestFactory innført i GWT 2.1 mot ExtGWT. Dette har til tider vært en frustrerende opplevelse, og ønsker her å publisere noen av de løsningene vi kom frem til slik at andre slipper å oppleve den samme frustrasjonen.
For GWT sine RPC-kall ønsker vi å konfigurere plassering av endepunkter gjennom Spring-annotasjoner. Dette krever at vi setter opp Spring-kontrollere i stedet for GWT-servlets. Denne integrasjonen gjøres i følgende kodebit.
-
public abstract class AbstractRpcController extends RemoteServiceServlet {
-
-
private static final Log logger = LogFactory.getLog(AbstractRpcController.class);
-
private ServletContext servletContext;
-
-
@Override
-
public final ServletContext getServletContext() {
-
return servletContext;
-
}
-
-
@Autowired
-
public final void setServletContext(final ServletContext servletContext) {
-
this.servletContext = servletContext;
-
}
-
-
public abstract RemoteService getRemoteService();
-
-
@RequestMapping("/")
-
public final void request(final HttpServletRequest request,
-
final HttpServletResponse response) {
-
this.doPost(request, response);
-
}
-
-
@Override
-
public final String processCall(final String payload)
-
throws SerializationException {
-
try {
-
RPCRequest rpcRequest =
-
RPC.decodeRequest(payload, this.getRemoteService().getClass());
-
String result =
-
RPC.invokeAndEncodeResponse(this.getRemoteService(),
-
rpcRequest.getMethod(), rpcRequest.getParameters());
-
return result;
-
} catch (IncompatibleRemoteServiceException ex) {
-
logger.error("Caught an exception", ex);
-
return RPC.encodeResponseForFailure(null, ex);
-
} catch (Exception ex) {
-
logger.error("Caught a generic exception", ex);
-
return RPC.encodeResponseForFailure(null, ex);
-
}
-
}
-
}
Selve kjernen her er den siste metoden. Her rutes en GWT-service inn til GWT sin implementasjon av RPC-behandling. Dette sørger for en sømløs integrasjon mellom GWT og Spring. Referanse til GWT-service er abstract, da hver modul-implementasjon bruker sin egen service.
-
@Controller
-
@SystemController
-
@RequestMapping("/rpc/contact")
-
public class ContactRpcController extends AbstractRpcController {
-
-
private ContactService contactService;
-
-
@Autowired
-
public final void setContactService(final ContactService contactService) {
-
this.contactService = contactService;
-
}
-
-
@Override
-
public final RemoteService getRemoteService() {
-
return this.contactService;
-
}
-
}
Dette er en implementasjon av en modul-spesifikk RPC kontroller. Kontakt-service hentes her fra Spring sin kontekst, og gis tilbake til den abstrakte implementasjonen ved behov. Dette gjør det raskt og enkelt å legge til services for andre moduler.
|
|
--Emner: Java, Utvikling, Web 2.0, WisWeb 2
|
|
|
VBA UrlEncode |
Av: Ove Halseth |
Lørdag 30.10.2010 (22:43) |
I ett prosjekt så hadde vi behov for å poste en url. Problemet var bare at æøå rotet til alt på serversiden, og vi fikk ikke ut parametrene.
Etter litt googling så fant vi fort diverse varianter av UrlEncode, deriblandt en versjon som skulle støtte UTF-8:
http://stackoverflow.com/questions/218181/how-can-i-url-encode-a-string-in-excel-vba
Men vi kom ikke helt i mål, for vi fikk ikke konverteringen til UTF-8 til å virke:-( Nytt dykk i google kom opp med:
http://www.codenewsgroups.net/vb/t13396-widechartomultibyte-utf-8.aspx
Som ga oss konvertering til UTF-8.
Resultatet ble:
Private Declare Function WideCharToMultiByte Lib "Kernel32.dll" ( _
ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, _
ByVal cchWideChar As Long, ByVal lpMultiByteStr As String, ByVal cbMultiByte As Long, _
ByVal lpDefaultChar As String, ByRef lpUsedDefaultChar As Long) As Long
Private Declare Function MultiByteToWideChar Lib "Kernel32.dll" ( _
ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As String, _
ByVal cbMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Const CP_UTF8 As Long = 65001 ' UTF-8 translation
Public Function ToUTF8(ByRef inString As String) As String
Dim BufLen As Long
BufLen = WideCharToMultiByte(CP_UTF8, 0&, ByVal StrPtr(inString), _
Len(inString), vbNullString, 0&, vbNullString, ByVal 0&)
If (BufLen > 0) Then
ToUTF8 = Space$(BufLen)
Call WideCharToMultiByte(CP_UTF8, 0&, ByVal StrPtr(inString), _
Len(inString), ToUTF8, BufLen, vbNullString, ByVal 0&)
End If
End Function
Public Function FromUTF8(ByRef inString As String) As String
Dim BufLen As Long
BufLen = MultiByteToWideChar(CP_UTF8, 0&, inString, -1, 0&, 0&)
If (BufLen > 0) Then
FromUTF8 = Space$(BufLen)
BufLen = MultiByteToWideChar(CP_UTF8, 0&, inString, _
Len(inString), ByVal StrPtr(FromUTF8), BufLen)
FromUTF8 = Left$(FromUTF8, BufLen) ' Trim null
End If
End Function
Public Function UrlEncode( _
StringVal As String, _
Optional SpaceAsPlus As Boolean = False, _
Optional UTF8Encode As Boolean = True _
) As String
Dim StringValCopy As String
Dim StringLen As Long
StringValCopy = IIf(UTF8Encode, ToUTF8(StringVal), StringVal)
StringLen = Len(StringValCopy)
If StringLen > 0 Then
ReDim Result(StringLen) As String
Dim I As Long, CharCode As Integer
Dim Char As String, Space As String
If SpaceAsPlus Then Space = "+" Else Space = "%20"
For I = 1 To StringLen
Char = Mid$(StringValCopy, I, 1)
CharCode = Asc(Char)
Select Case CharCode
Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
Result(I) = Char
Case 32
Result(I) = Space
Case 0 To 15
Result(I) = "%0" & Hex(CharCode)
Case Else
Result(I) = "%" & Hex(CharCode)
End Select
Next I
UrlEncode = Join(Result, "")
End If
End Function
'From http://stackoverflow.com/questions/218181/how-can-i-url-encode-a-string-in-excel-vba
Public Function UrlEncode( _
StringVal As String, _
Optional SpaceAsPlus As Boolean = False, _
Optional UTF8Encode As Boolean = True _
) As String
Dim StringValCopy As String
Dim StringLen As Long
StringValCopy = IIf(UTF8Encode, ToUTF8(StringVal), StringVal)
StringLen = Len(StringValCopy)
If StringLen > 0 Then
ReDim Result(StringLen) As String
Dim I As Long, CharCode As Integer
Dim Char As String, Space As String
If SpaceAsPlus Then Space = "+" Else Space = "%20"
For I = 1 To StringLen
Char = Mid$(StringValCopy, I, 1)
CharCode = Asc(Char)
Select Case CharCode
Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
Result(I) = Char
Case 32
Result(I) = Space
Case 0 To 15
Result(I) = "%0" & Hex(CharCode)
Case Else
Result(I) = "%" & Hex(CharCode)
End Select
Next I
UrlEncode = Join(Result, "")
End If
End Function
Ove B-)
|
|
--Emner: Access, Utvikling, VBA
|
|
|
Kan ikke slette i de angitte tabellene |
Av: Ove Halseth |
Mandag 23.08.2010 (07:22) |
Ofte når jeg støter på problemer i Windows så har jeg på følelsen av at det finns sikkert en sjekkboks for dette problemet ett sted.
Problemet er bare og finne ut hva sjekkboksen heter og hvor den er gjemt.
Grunnen til at du leser denne bloggen er kanskje fordi du har støtt borti denne feilmeldingen i MSAccess:
"Kan ikke slette i de angitte tabellene"
Da har jeg en god nyhet! Om ikke en sjekkboks så fins det en setting som "slår av" denne feilmeldingen.
- Når du har spørringen fremme, så trykk Alt-Enter for å få frem egenskapssiden til spørringen.
- Her setter du Entydige poster til Ja.
Entydige poster er altså navnet på dette problemets hake...
Løsningen ble funnet hos Microsoft kundestøtte! Etter litt googling.
Mvh
Ove B-) |
|
--Emner: Access, Database/SQL, Utvikling
|
|
|
De tre gruppene av utviklere |
Av: Stig Runar Vangen |
Mandag 08.03.2010 (00:00) |
I forbindelse med mitt GameLib-prosjekt brukte vi klassifisering av utviklere fra Microsoft. Fant igjen denne artikkelen om forskjellige utvilkler-grupper, og bestemte meg for å oversette og legge ut denne teksten. Merk at denne sammenligningen bare sammenligner hvordan utviklergruppene tenker rundt bruken av tredjeparts biblioteker. For en mer humoristisk generell sammenligning, se også her.
Systematisk utviklere (Systematic programmers) har en tendens til å følge en defensiv koding stil. De gjør ikke antagelser om koden de skriver, plattformen den kjører på, klasse-bibliotekene som de bruker osv. For eksempel vil de ikke anta at et klasse-biblioteket vil oppføre seg som annonsert. I stedet vil systematiske utviklere teste biblioteket i et trygt miljø, inspisere bibliotekets kildekode etc før de bruker den i et produksjonsmiljø. Systematiske utviklere ønsker programmeringsspråk og APIer som gir dem full kontroll over eksekveringen av koden sin, og som ikke skjuler viktige detaljer fra dem, selv om det betyr at de må skrive mer kode og bruke mer tid på å forstå hvordan koden virker. De verdsetter å kunne komme under overflaten og finpusse komponenter eller erstatte dem.
Pragmatiske utviklere (Pragmatic programmers) har en tendens til å være mindre defensiv enn systematiske utviklere. I mange tilfeller er de mer komfortable med å gri fra seg kontrollen over koden for bedre produktivitet så lenge de er klar over fordelene de vinner. I stedet for å bruke tid på å oppnå en full forståelse av alle detaljer rundt et API, vil de foretrekker å lære underveis, å bygge opp forståelse for APIet samtidig med det arbeidet de gjør. De verdsetter å kunne komme under overflaten og finpusse komponenter når de må, men vil helst ikke måtte gjøre det.
Opportunistiske utviklere (Opportunistic programmers) verdsetter produktivitets-funksjoner i et språk, API eller IDE svært høyt, ofte høyere enn noe annet. I motsetning til systematiske utviklere, setter de mindre verdi i å ha full kontroll over koden deres, siden for opportunistiske utviklere kontrollen over koden mindre verdt enn utviklings-tid. De særlig verdsetter 3. parts komponenter og APIer som tillater dem å konsentrere seg om virksomhetens problemet som de prøver å løse, snarere enn på konfigurering av komponenter eller tilpasser API slik at det oppfyller deres krav. De ser ingen verdi i å kunne komme under overflate og tilpasse komponenter - de ville heller lete etter et annet API eller komponent som møter deres behov fremfor å endre komponenter eller APIer som de allerede har.
Hvilken type utvikler er du?
|
|
--Emner: Utvikling
|
|
|
|
|